首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >useEffect中的useState不更新状态

useEffect中的useState不更新状态
EN

Stack Overflow用户
提问于 2020-10-04 14:52:48
回答 4查看 5.1K关注 0票数 3

我是第一次接触React Hooks和使用react 16.13.1。

我将实现Auth组件,它可以处理登录。

但是,即使使用response Object调用setCurrentUser,它似乎也没有正确更新状态currentUser

这段代码有什么问题?

代码语言:javascript
复制
import React, { useState, useEffect } from "react";
import { Route, Redirect } from "react-router-dom";
import { checkLoggedIn } from "utils/Api";

export const Auth = (props) => {
  const [currentUser, setCurrentUser] = useState(null);
  const [isLoading, setIsLoading] = useState(false);
  console.log(currentUser);

  useEffect(() => {
    const f = async () => {
      setIsLoading(true);
      console.log(isLoading);
      const res = await checkLoggedIn();
      if (!!res) { // ==> true
        setCurrentUser(res);
        console.log(currentUser); // ==> null!
      }
      setIsLoading(false);
    };
    f();
  });

  if (isLoading) {
    return <div>loading</div>;
  }

  console.log(currentUser); // ==> null!
  return !!currentUser ? (
    <Route children={props.children} />
  ) : (
    <Redirect to={"/login"} />
  );
};
EN

回答 4

Stack Overflow用户

发布于 2020-10-04 15:07:56

setCurrentUser异步地更新状态,因此您不能在之后立即使用currentUser

但是,您可以使用另一个useEffect来了解状态更改的时间:

代码语言:javascript
复制
useEffect(() => {
  // currentUser changed
}, [currentUser])

我还注意到,您没有将空数组传递给已有的useEffect,因此它将在组件每次更新时触发。如果您只需要执行一次useEffect,则必须传递一个空数组作为第二个参数,如下所示:

代码语言:javascript
复制
  useEffect(() => {
    const f = async () => {
      // ...
    };
    f();
  }, []);
票数 6
EN

Stack Overflow用户

发布于 2020-10-04 15:40:40

因为@germanescobar已经响应了,所以setCurrentUser异步更新状态。因此,您需要使用仅包含currentUser的依赖项列表进行useEffect,以获取最新的状态值。

但是,对于您的用例,您只对currentUser是否真实感兴趣,并基于此将用户重定向到所需的页面。因此,您不需要另一个useEffect,因为您不会基于currentUser执行任何其他副作用。

在实际场景中,您希望显示加载/启动屏幕,直到您能够确定用户是否通过身份验证。因此,您应该将isLoading的初始值更改为true,并在完成异步任务后将状态更改为false。我建议您将州名称重命名为类似如下的名称:

const [shouldCheckLogin, setShouldCheckLogin] = useState(true)

最后,!!nullfalse,而!!{}true。对于object的值,用null初始化它们是完全可以的。

代码语言:javascript
复制
console.log(!!null)
console.log(!!{})

票数 3
EN

Stack Overflow用户

发布于 2020-10-04 15:11:25

由于在React中设置状态的异步性质,调用状态的设置器(setCurrentUser)可能会出现问题。我还没有找到明确的答案,当我使用React时,它是异步的setState还是同步的。在我看来,在这种复杂的情况下,最好的解决方案就是使用类。它将为您提供许多使用钩子无法重现的生命周期方法,在auth组件中会更合适。React Hooks并不是在所有情况下都是类的替代品,它只是一个工具,它允许您在只需要进行简单改进的情况下不破坏现有代码。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64191896

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档