useState Hook 异步函数的并发问题

问题描述 投票:0回答:0
这是我遇到、调查并解决的问题,我想与您分享我的经验。

我发现当你使用 useState HOOK 来维护状态,然后在异步函数中使用

setState({...state, updatedProperty: updatedValue})

 风格更新状态时,你可能会遇到一些并发问题。

在某些情况下,这可能会导致应用程序丢失一些数据,因为异步函数保留状态的隔离版本,并且可能会覆盖状态中存储的其他组件的数据。

修复,简而言之:

如果要从异步函数更新状态,则需要使用减速器来更新状态或使用设置状态的函数更新器版本,因为函数更新器获取状态的最新更新版本作为参数(prevState)

setState(prevState => ({...prevState, updatedProperty: updatedValue});


详细描述:

我正在开发数据上下文来管理保存在数据库中的用户联系人,该数据库托管在云 MongoDB 集群上并由后端 Web 服务管理。

在上下文提供程序中,我使用 useState 挂钩来维护状态并按如下方式更新它

const [state, setState] = useState({ contacts: [], selectedContact: null }); const setSelected = (contact) => setState({...state, selectedContact: contact}); const clearSelected = ()=> setState({...state, selectedContact: null}; const updateContact = async(selectedContact) => { const res = await [some api call to update the contact in the db]; const updatedContact = res.data; // To check the value of the state inside this function, I added the following like and found // selectedContact wasn't null although clearSelected was called directly after this function and // selectedContact was set to null in Chrome's React dev tools state viewer console.log('State Value: ' + JSON.stringify(state)); //The following call will set selectedContact back to the old value. setState({ ...state, contacts: state.contacts.map(ct=> ct._id === updatedContact._id? updatedContact : ct) }); } //In the edit contact form submit event, I called previous functions in the following order. updateContact(); clearSelected();

问题

发现 selecteContact 设置为 null 后,在 updateContact 完成等待 api 调用的承诺后设置回所选联系人的旧值。

当我使用函数更新程序更新状态时,此问题已得到解决

setState(prevState => ({ ...prevState, contacts: prevState.contacts.map(ct=> ct._id === updatedContact._id? updatedContact : ct) }));
我还尝试使用减速器来测试这个问题的行为,发现减速器工作正常,即使您打算使用常规方式(不使用函数更新器)来更新状态。

reactjs react-hooks async-await reduce
© www.soinside.com 2019 - 2024. All rights reserved.