繁体   English   中英

反应:在 useEffect 挂钩中的网络请求后更新然后访问 state。 State 仍然过时

[英]React : Updating and then accessing state after a network request in useEffect hook. State remains stale

我试图更新和引用我的组件的初始化 function 内部的hasError state 字段,以控制在成功初始化后是否发生重定向或是否显示错误。

这是该问题的精简版:

const [hasError, setHasError] = useState(false);

useEffect(() => {
  initialize();
}, []);

async function initialize(){
  try {
    await networkRequest();
  } catch (err) {
    setHasError(true);
  }
  console.log(hasError);  // <- is still false
  if(!hasError){
    redirect()  // <- causes redirect even with error
  }
}

function networkRequest() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject();
    }, 1000);
  });
}

初始化 function 应该只在组件安装时调用一次,这就是我将[]传递给useEffect的原因。 [hasError]传递给useEffect也没有意义,因为我不希望每次hasError更新时都运行初始化。

我见过人们推荐使用useReducer但这似乎很棘手,因为我已经在这个组件上使用了 Redux ,然后我需要使用 2 个不同的dispatch实例。

通常如何处理这样的用例?

您将不得不创建另一个useEffect钩子来“监听”对hasError的更改。 在这种情况下, setHasError是异步的,因此新值不会立即提供给您。

我不知道你的组件的 rest 是什么样子的,但听起来你应该有某种isLoading state 用于显示loading消息,然后一旦你的请求完成并且失败,你就会呈现你需要的东西,或者如果它成功,你redirect

这是一个例子:

function App() {
  const [isLoading, setIsLoading] = useState(true);
  const [hasError, setHasError] = useState(false);

  useEffect(() => {
    (async () => {
      try {
        await networkRequest();
        isLoading(false);
      } catch (error) {
        setHasError(error);
        isLoading(false);
      }
    })()
  }, [])

  useEffect(() => {
    if (!isLoading && !hasError) {
      redirect();
    }
  }, [isLoading, hasError]);

  if (isLoading) { return "Loading"; }
  
  // else, do whatever you need to do here
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM