reactjs - React useState Hooks - 在一个状态中管理多个加载状态
问题描述
我正在尝试使用反应挂钩动态管理状态内的多个加载状态。
但是,当我根据 api 调用的结果(成功或错误)更新状态对象时,它会产生一个非常奇怪的结果。
在我下面的代码示例中,单击按钮将触发按钮的加载状态为真。
当我在按钮 1 进行呼叫时单击按钮 1,然后单击按钮 2(这里我只是模拟超时),它们都按预期将加载状态设置为 true。
然后,一段时间后,两个加载状态都设置为 false。
但是,然后两个调用都完成了,按钮 1 加载状态再次设置为 true ......!?
我不确定如何解决这个问题,感谢您的帮助。谢谢你。
https://codesandbox.io/s/usestate-async-timeout-issue-oknvu
import React, { useState } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
const [loading, setLoading] = useState({});
const handleOnClick = id => {
setLoading({ ...loading, [id]: true });
setTimeout(() => {
// simulate the case for when error is returned after an api call.
setLoading({ ...loading, [id]: false });
}, 2000);
};
return (
<div className="App">
<h1>React UseState: Updating a state object</h1>
{["1", "2"].map(id => {
return !loading[id] ? (
<button key={id} onClick={() => handleOnClick(id)}>
Item {id}
</button>
) : (
"Loading..."
);
})}
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
解决方案
React 中的状态更新不是同步的,当您根据之前的状态更新状态时,这是一个常见的问题。我认为您需要进行以下更改:
const handleOnClick = id => {
setLoading(prev => ({ ...prev, [id]: true }));
setTimeout(() => {
// simulate the case for when error is returned after an api call.
setLoading(prev => ({ ...prev, [id]: false }));
}, 2000);
};
我已经更改了这两setLoading
行以在其更新中使用以前的状态。
您可以在此处阅读有关此内容的更多信息:
https://reactjs.org/docs/hooks-reference.html#functional-updates
推荐阅读
- html - 如何根据某些屏幕尺寸传递某些道具
- polymer-3.x - 将函数传递给孩子
- android - 如何在没有太多代码更改的情况下使相对布局应用程序响应?
- javascript - 用户签到位置基于从哪里开始?
- python - 修改“max_depth”时,如何将 DecisionTreeRegressor 的结果保存到不同的数组?
- python - 错误的 Word() 字符串给出了误导性的错误位置
- r - 使用 dplyr 中的“包含”使用多列创建指标变量
- sql - 在插入或更新时返回数据时,我还需要使用 Exec 吗?
- c++ - 如何处理模棱两可的模板参数?
- ios - 两个同时滚动的视图行为怪异