自React 16起,由于支持异步componentWillUnmount,因此不再保证componentWillMount
和componentWillUnmount
的排序。
在我们使用React + Redux的项目中,但是,从页面A导航到页面B,例如,页面A调用componentWillUnmount
来清理应用程序状态,然后跳转到页面B,调用{{1获取数据并更新状态。由于它们的排序无法控制,有时状态会搞砸。
这个问题的最佳解决方案是什么?
答案 0 :(得分:1)
如果可能的话,我会在Redux中分离状态,因此不会在页面之间共享状态:https://github.com/reactjs/redux/blob/master/docs/api/combineReducers.md
如果不可能,您可以尝试将您的逻辑添加到导航功能中。
您的问题的更多细节可能有助于我进行调试,例如您用于路由的内容以及状态。
有关迁移到新生命周期方法的更多信息,请查看此处: https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#migrating-from-legacy-lifecycles
答案 1 :(得分:1)
componentWillMount
生命周期方法并迁移到使用新引入的方法我们学到的最大教训之一是,我们的一些遗留组件生命周期往往会鼓励不安全的编码实践。他们是:
componentWillMount componentWillReceiveProps componentWillUpdate 这些生命周期方法经常被误解和巧妙地误用;此外,我们预计,对于异步渲染,它们的潜在误用可能会更成问题。因此,我们将在即将发布的版本中为这些生命周期添加“UNSAFE_”前缀。 (这里,“不安全”不是指安全性,而是传达使用这些生命周期的代码更有可能在React的未来版本中出现错误,特别是在启用异步渲染后。)
你应该用componentDidUpdate
生命周期方法进行数据提取,我更喜欢用getDerivedStateFromProps(nextProps, prevState)
方法捕捉道具。
我解释了一点In this stackoverflow post并且有一个使用此方法的例子。
答案 2 :(得分:1)
有几种方法可以解决这个问题。但是几乎所有这些都是不好的做法(例如,在首次渲染中使用HOC并返回null,然后清理并执行异步查询等)我不推荐这样的方法。
因此,我建议您花一点时间来重构您的体系结构并将Redux中的状态分开。 我找到了一篇关于这个问题的好Dan Abramov的帖子:https://github.com/facebook/react/issues/11106#issuecomment-344573660
最简单的方法是不以这种方式重用树的相同部分。想一想:通常期望组件是独立的。如果同时渲染两个这样的“独占”组件会发生什么?他们会发生冲突。这似乎不是正确的组件思考。
我理解避免这种模式的代码更多,但在我的经验中,用对象或数组替换单个状态树分支就足够了。例如,您可以通过ID(即使是动态生成的ID)对其进行键入,然后不是及时拆除旧组件以进行新组件安装,您只需将新组件指向具有新ID的分支,同时保持老人活着。然后最终你可以发出一个动作来清理未使用的状态分支,只留下具有最新ID的那个。