在没有任何新状态值的情况下,将"setState"作为函数中的回调调用,如何成功更新状态?



我最近看到了这个代码片段,我想知道状态变量实际上是如何在这里更新的。这是 Firebase 身份验证中使用的身份验证状态观察器,用于确定用户是否已登录(文档参考(。 通常,它是这样运作的:

const [userData, setUserData] = useState(null)
firebase.auth().onAuthStateChanged(user => {
if (user) {
// User is signed in.
setUserData(user); // can now access properties of user
}
});

但是,此代码以完全相同的方式更新userData,方法是将setUserData放在函数中的回调位置:

const [userData, setUserData] = useState(null)
firebase.auth().onAuthStateChanged(setUserData);

这两个函数都将userData设置为同一对象。在第二个代码段中,通过不使用有形值来更新状态来更新状态,这是如何工作的?

第二个调用使用在其他地方定义的函数作为回调,而第一个调用使用新定义的函数。

请参阅以下示例:

function log(data) {
console.log(data);
}
function someFunction(callback) {
setTimeout(()=>{ callback("my data")}, 1000);
}
someFunction( (data)=> console.log(data) ); // use new function
someFunction( log ); // reuse a defined function

这就是它在javascript中的工作方式。函数是一等公民,您可以将其分配给变量并作为参数传递。在这里,setUserData作为onAuthStateChanged的第一个参数传递。为了更好地理解,请考虑如下内容:

const [userData, setUserData] = useState(null)
const handleAuth = user => {
if (user) {
setUserData(user);
}
}
firebase.auth().onAuthStateChanged(handleAuth);

setUserDatahandleAuth都希望user作为第一个参数,因此这两个函数都可以作为回调传递给onAuthStateChanged

以下两种方式是相同的:

firebase.auth().onAuthStateChanged(user => setUserData(user))
// OR,
firebase.auth().onAuthStateChanged(setUserData)

因此,当您使用箭头函数时,您显式地将用户设置为参数来设置UserData,而当您将其用作回调时,它会隐式地将用户参数设置为它。

最新更新