React:promise 内的 setState 不会更改状态值

问题描述 投票:0回答:2

我有以下代码:

function App() {

 const [appData, setAppData] = useState(initialAppDataValue);
const [test, setTest] = useState("");

// outside useEffect
if(!DataProviderService.isInitialized){
    fetchData();
}

// inside useEffect
/*useEffect(() => {
    fetchData();
}, []);*/

function fetchData(){
    DataProviderService.getAppData().then((data) => {
        setAppData(data);
        setTest("abc");
    });
}

return (<div>something...</div>);
}

如果我在 useEffect 外部调用“fetchData”,则状态更新不起作用,但如果我在 useEffect 内部调用“fetchData”,则状态更新工作正常。

我的问题是为什么? 在 useEffect 之外,我更新了状态,然后我看到调用了重新渲染,但该值不包含新值。我不明白为什么。

javascript reactjs react-hooks setstate
2个回答
0
投票

在此代码中,当组件渲染时调用 fetchData。 首次渲染时,DataProviderService 未初始化,且 fetchData 未调用。 之后,不会更改任何状态或道具,并且不会再次重新渲染组件,并且不会调用 fetchData。


0
投票

*当您在 useEffect 之外调用 fetchData 时,它会在组件渲染时立即运行。 DataProviderService.getAppData().then(...) 部分是异步的,这意味着它在进入下一行代码并启动进程之前不会等待结果,但不会等待。 setAppData 和 setTest 是更新组件状态的函数。当状态更新时,它会触发组件的重新渲染。我们知道 Promise 是异步的,在重新渲染发生时状态更新可能尚未完成。这可能会导致组件使用旧状态值重新渲染。

当你将 fetchData 放入带有空 [] 的 useEffect 中时,它确保 fetchData 仅在组件首次显示时执行一次。DataProviderService.getAppData().then(...) 部分正在做一些工作,它需要时间才能完成。但现在,因为 fetchData 位于 useEffect 内部,所以组件渲染时它不会立即运行。useEffect 捕获组件第一次显示在屏幕上的时间。它等待异步工作 (DataProviderService.getAppData().then(...)) 完成后再继续。异步工作完成后,使用 setAppData 和 setTest 更新状态。这会触发重新渲染,但现在重新渲染发生在异步任务完成之后。因此,当组件重新渲染时,它会显示更新的正确信息。*

© www.soinside.com 2019 - 2024. All rights reserved.