带有空数组的 useEffect 的行为不像 componentDidMount() [英] useEffect with empty array doesn't behave as componentDidMount()
问题描述
我有以下问题.我需要在 onSnapshot 事件之后设置应用程序组件的状态.这就是为什么我把它放在 componentDidMount() 中,它工作正常,它记录了设置的用户,但是当我把相同的代码放在一个带有空依赖数组的 useEffect 中时,它记录为空.有什么想法吗?
这里有两个组件:
类
class App extends Component<{}, AppState>{构造函数(道具:任何){超级(道具);this.state = {当前用户:未定义,};}unsubscribeFromAuth = () =>{};componentDidMount() {this.unsubscribeFromAuth = auth.onAuthStateChanged(async (userAuth) => {如果(用户身份验证){const userRef = await createUserProfileDoc(userAuth);userRef?.onSnapshot((snapShot) => {this.setState({当前用户: {id: snapShot.id,...snapShot.data(),},});控制台日志(这个状态);});}});}componentWillUnmount() {this.unsubscribeFromAuth();}使成为() {返回 (<div><Header currentUser={this.state.currentUser}/><开关><路由精确路径="/";组件={主页}/><路线路径="/shop";组件={ShopPage}/><路由路径="/signin";组件={SignInUpPage}/></开关>
);}}
功能性
function App() {const [currentUser, setCurrentUser] = useState {让 unsubscribeFromAuth = () =>{};const afterMount = () =>{unsubscribeFromAuth = auth.onAuthStateChanged(async (userAuth) => {如果(用户身份验证){const userRef = await createUserProfileDoc(userAuth);userRef?.onSnapshot((snapShot) => {设置当前用户({id: snapShot.id,...snapShot.data(),});控制台日志(当前用户);});}});};后挂载();返回 () =>{unsubscribeFromAuth();};}, []);返回 (<div><Header currentUser={currentUser}/><开关><路由精确路径="/";组件={主页}/><路线路径="/shop";组件={ShopPage}/><路由路径="/signin";组件={SignInUpPage}/></开关>
);}导出默认应用程序;
在同一函数中设置状态和控制台记录该状态的当前值将始终返回旧值.
试试这个:
useEffect(()=>{//...const newCurrentUser = { id: snapShot.id,...snapShot.data(),}设置当前用户(新当前用户);控制台日志(新当前用户);
//在useEffect()之外console.log(currentUser)//<<---在 useEffect 完成其工作后,您将首先看到 null 然后是实际的当前用户
I have the following problem. I need to set the state of the app component after the onSnapshot event. That's why I have put that in the componentDidMount() and it works fine it logs the set user, however when I put the same code in a useEffect with an empty dependency array it logs null. Any ideas?
Here are the two components:
Class
class App extends Component<{}, AppState> {
constructor(props: any) {
super(props);
this.state = {
currentUser: undefined,
};
}
unsubscribeFromAuth = () => {};
componentDidMount() {
this.unsubscribeFromAuth = auth.onAuthStateChanged(async (userAuth) => {
if (userAuth) {
const userRef = await createUserProfileDoc(userAuth);
userRef?.onSnapshot((snapShot) => {
this.setState({
currentUser: {
id: snapShot.id,
...snapShot.data(),
},
});
console.log(this.state);
});
}
});
}
componentWillUnmount() {
this.unsubscribeFromAuth();
}
render() {
return (
<div>
<Header currentUser={this.state.currentUser} />
<Switch>
<Route exact path="/" component={HomePage} />
<Route path="/shop" component={ShopPage} />
<Route path="/signin" component={SignInUpPage} />
</Switch>
</div>
);
}
}
Functional
function App() {
const [currentUser, setCurrentUser] = useState<User | null>(null);
useEffect(() => {
let unsubscribeFromAuth = () => {};
const afterMount = () => {
unsubscribeFromAuth = auth.onAuthStateChanged(async (userAuth) => {
if (userAuth) {
const userRef = await createUserProfileDoc(userAuth);
userRef?.onSnapshot((snapShot) => {
setCurrentUser({
id: snapShot.id,
...snapShot.data(),
});
console.log(currentUser);
});
}
});
};
afterMount();
return () => {
unsubscribeFromAuth();
};
}, []);
return (
<div>
<Header currentUser={currentUser} />
<Switch>
<Route exact path="/" component={HomePage} />
<Route path="/shop" component={ShopPage} />
<Route path="/signin" component={SignInUpPage} />
</Switch>
</div>
);
}
export default App;
Setting state and console logging the current value of that state in the same function will always return the old value.
Try this:
useEffect(()=>{
//...
const newCurrentUser = { id: snapShot.id,
...snapShot.data(),
}
setCurrentUser(newCurrentUser);
console.log(newCurrentUser);
//outside the useEffect()
console.log(currentUser) //<<---You will first see null then the actual current user after useEffect is done doing its work
这篇关于带有空数组的 useEffect 的行为不像 componentDidMount()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!