在 firebase.utils.js 上的函数内部传递道具

Posted

技术标签:

【中文标题】在 firebase.utils.js 上的函数内部传递道具【英文标题】:Pass props inside function on firebase.utils.js 【发布时间】:2020-10-03 04:47:03 【问题描述】:

我有一个奇怪的问题,但我真的无法解决它,而且我已经绊倒了好几天了。

这里我有一个功能组件 - 注册:

const SignUp = () => 
  const [user, setUser] = useState(
    displayName: "",
    email: "",
    password: "",
    confirmPassword: "",
  );

  const handleSubmit = async (event) => 
    event.preventDefault();

    const  displayName, email, password, confirmPassword  = user;

    if (password !== confirmPassword) 
      alert("Passwords don't match");
      return;
    

    try 
      const  newUser  = await auth.createUserWithEmailAndPassword(
        email,
        password
      );

      console.log('SignUp displayName: ', displayName);

      await createUserProfileDocument(newUser, displayName);

      setUser(
        displayName: "",
        email: "",
        password: "",
        confirmPassword: "",
      );
     catch (err) 
      console.log(err);
    
  ;

  const handleChange = (event) => 
    const  name, value  = event.target;
    setUser( ...user, [name]: value );
  ;

  return (
    // Form with displayName, email, password, confirmPassword inputs
  );
;

这是 firebase.utils 中的“createUserProfileDocument”函数:

export const createUserProfileDocument = async (userAuth, additionalData) => 
    if (!userAuth) return;

    const userRef = firestore.doc(`users/$userAuth.uid`);

    // const snapShot = await userRef.get();

    console.log('additionalData: ', additionalData);

    console.log('userAuth: ', userAuth);

    // if (!snapShot.exists) 
    //     const  displayName, email  = userAuth;
    //     const createdAt = new Date();
    //     try 
    //         await userRef.set(
    //             displayName,
    //             email,
    //             createdAt,
    //             ...additionalData
    //         );
    //      catch (err) 
    //         console.log('error creating user', err.message);
    //     
    // 

    return userRef;
;

此代码的问题是,当我提交表单时,它触发了调用 createUserProfileDocument 函数的 handleSubmit。此时,它正确获取了 userAuth 对象,但没有得到任何“additionalData”道具,改为显示未定义..

这可能是什么原因?我可以确认 form 和 handleChange 都正常工作,用插入的值更新用户钩子状态

我在 SignUp 组件(handleSubmit 内部)上添加的 console.log 正确显示了 displayName;另一方面,firebase.utils 中的 console.logs 显示 userAuth,但没有获取这些附加数据(在本例中为 displayName),而是未定义

我从 console.logs 得到的信息如下:

在 userAuth 上我仍然没有得到任何 displayName 但可以检索电子邮件:

这是填写表单后保存的用户属性:

在传递道具这样简单的事情上,我真的不明白我做错了什么...... 也许 createUserProfileDocument 函数在 displayName 被传递到 handleSubmit 之前被调用? (不得不说我对异步等待还没有完全信心,所以这可能是与钩子结合的原因)

提前感谢您帮助发现此问题!

【问题讨论】:

如果console.log(displayName) 在调用createUserProfileDocument 之前显示正确的值,我看不出additionalData 的值未定义的原因。能分享一下日志截图吗?因为我在函数体的注释掉的代码中看到了...additionalData,所以我怀疑additionalData 值需要是一个对象,但是在调用createUserProfileDocument 时,您只传递了displayName 的字符串值。因此,如果您尝试访问additionalData.displayName,显然它将是undefined。如果我遗漏了什么,请告诉我。 嗨 subashMahapatra,首先感谢您再次帮助我。我注释掉了扩展的附加数据,因为将来我希望能够传递的不仅仅是一个道具;为此,我将在 SignUp 组件上传递一个对象,如下所示: await createUserProfileDocument(newUser, displayName, otherProps );但现在这无关紧要; displayName 作为 user.displayName 存储在用户内部,到目前为止,这是我必须传递给 createUserProfileDocument 函数的唯一属性 - 希望能解释 我注意到的另一件事,函数createUserWithEmailAndPassword 的返回类型是Promise<UserCredential> UserCredential,它不包含任何名称为newUser 的属性,但它具有名称为@ 的属性987654343@。您应该解构属性user 而不是newUserconst user = await auth.createUserWithEmailAndPassword(email, password); 是的,这就是我将附加数据设为未定义的原因!我会给你成千上万的赞许,干得好,最重要的是非常感谢你花时间帮助我! p.s.不过这很奇怪 是的,我仍然无法理解为什么会发生这种奇怪的行为。我将发布解决方案作为答案。 【参考方案1】:

方法createUserWithEmailAndPassword 返回一个Promise<UserCredential> 类型的值,而UserCredential 的值没有newUser 的属性名称。它包含属性user 中的用户数据。

问题的解决方案

const  user  = await auth.createUserWithEmailAndPassword(email, password);

附: - 虽然上面的代码解决了这个问题,但我仍然非常不确定为什么 createUserProfileDocument 使用值 newUser(未定义)作为第一个参数调用时,additionalData(第二个参数)的值是 undefined,并且displayName 一个字符串值作为第二个参数。

如果有人知道这种行为的原因,请告诉我并随时编辑答案。

【讨论】:

以上是关于在 firebase.utils.js 上的函数内部传递道具的主要内容,如果未能解决你的问题,请参考以下文章

在监听器上的$内调用'this'函数[duplicate]

使用代码:Linux 上的块在 C++ 中的函数中的“未在范围内声明”

js构造函数的方法与原型prototype

如何在流星内访问客户端上的服务器聚合

引用查询函数中的单元格不包含在谷歌表格的范围内

命名空间内的局部函数声明