【发布时间】:2020-08-08 03:06:50
【问题描述】:
我在一个项目中使用 React 16.12.0,React Router DOM 5.1.2,并且只有在成功更新状态后才能重定向。基本上我有一个按钮,当点击时,我想用用户选择的信息更新状态,然后导航到主页并显示横幅。我正在使用封装在最高组件级别之一的 React Hook useContext,以及来自 React Router Dom 的历史对象。
预期行为:
- 上下文状态属性“showBanner”设置为 true
- 导航到“/”页面
现有行为:
- 导航到“/”页面
- 上下文状态属性“showBanner”仍然为假
这是代码的sn-p:
// Import statements - useHistory() from react-router-dom, useContext from react, etc.
const browse = (props) => {
const {globalState, dispatchGlobalState} = useContext(myContext);
const history = useHistory();
const handleButtonClick = (e) => {
dispatchGlobalState( { type: 'showBanner', payload: true } );
history.push('/');
}
return (
<button onClick={handleButtonClick}>Click Me</button>
)
我也试过用 Promise 包装调度,但没有运气......
const handleButtonClick = (e) => {
new Promise( (resolve, reject) ) => {
dispatchGlobalState( { type: 'showBanner', payload: true } );
})
.then( () => {
history.push('/');
}));
我也尝试过使用本地状态有条件地渲染元素,但也没有运气。有谁知道我可能做错了什么 - 我如何告诉 React 首先进行我所有的状态更新,并且只有在完成后,然后重定向到另一个页面?
【问题讨论】:
-
我认为那里发生了竞争情况。虽然这不是最佳实践,但您可以尝试 setTimeout。即 setTimeout(()=>history.push('/'),0)
-
是的,这完全是一种竞争条件。由于两者都是异步操作的,因此有时会显示横幅(意味着首先更新全局状态,然后发生重定向)。并且有时它不显示(意味着在全局状态有机会更新之前首先触发重定向)。
-
setTimeOut 工作了吗?
-
我认为我们遇到了同样的问题。即使使用了 setTimeOut,仍然不能保证 dispatchGobalState 会在它之前成功运行,对吧?
标签: javascript reactjs react-router