首页 > 解决方案 > 为什么在 firebase.auth().createUserWithEmailAndPassword() 调用后 useRef() 挂钩设置为 null?

问题描述

useRef()像这样使用:

const firstname = useRef('');

const lastname = useRef('');

const email = useRef('');

const passwordOne = useRef('');

当我这样写时:

try {
    const authUser = await Firebase.auth
        .createUserWithEmailAndPassword(
            email.current.value,
            passwordOne.current.value
        );
    await Firebase.firestore.doc(`users/${authUser.user.uid}`).set({
        firstname: firstname.current.value,
        lastname: lastname.current.value,
        email: email.current.value
    });
    history.push(ROUTES.SIGN_IN);
}
catch (error) {
    setError(error.message);
}

我收到一个错误cannot read property value of null

但这是有效的:

try {
    const user = {
        firstname: firstname.current.value,
        lastname: lastname.current.value,
        email: email.current.value
    };
    const authUser = await Firebase.auth
        .createUserWithEmailAndPassword(
            email.current.value,
            passwordOne.current.value
        );
    await Firebase.firestore.doc(`users/${authUser.user.uid}`).set(user);
    history.push(ROUTES.SIGN_IN);
}
catch (error) {
    setError(error.message);
}

如何?为什么?

标签: javascriptreactjsgoogle-cloud-firestorefirebase-authenticationuse-ref

解决方案


您必须记住的一件重要事情是您正在处理异步代码,await不能保证语句尝试访问 ref 属性的时间,并且 refs 可能尚未初始化。

我的建议是重构您的代码以使用受控组件useState不是处理 DOM refsuseRef

在 HTML 中,<input>、<textarea> 和 <select> 等表单元素通常会维护自己的状态并根据用户输入对其进行更新。在 React 中,可变状态通常保存在组件的 state 属性中,并且只能使用 setState() 进行更新。我们可以通过使 React 状态成为“单一事实来源”来将两者结合起来。然后,呈现表单的 React 组件还控制后续用户输入在该表单中发生的情况。以这种方式由 React 控制其值的输入表单元素称为“受控组件”。


推荐阅读