这咋了呢?
今天在学习React-redux的时候,在将一个大组件拆分成UI组件和容器组件之后,突然报了这个错误:
getInputChangeAction = (value) => ({
type: 'change_input_value',
value
})
handleInputChange(e) {
const action = getInputChangeAction(e.target.value);
store.dispatch(action);
}
handleStoreChange() {
this.setState(store.getState());
}
This synthetic event is reused for performance reasons. If you're seeing this, you're accessing the property 'nativeEvent' on a released/nullified synthetic event. This is set to null. If you must keep the original synthetic event around, use event.persist().
SyntheticEvent
对象是通过合并得到的。 这意味着在事件回调被调用后,SyntheticEvent
对象将被重用并且所有属性都将被取消。这是出于性能原因。因此,您无法以异步方式访问该事件。
咋解决呢?
这说明我们正在使用的e.target
处于异步操作中,查询文档发现,如果你想异步访问事件属性,你需在事件上调用event.persist()
,此方法会从事件池中移除合成事件,允许用户代码保留对事件的引用。 姑且算是把警告消除了。
然鹅!这并不是一个合格的学习者的心态,我们需要刨根问底!
在使用某度搜索后,得知这样一个知识点:
Think of setState() as a request rather than an immediate command to update the component. For better perceived performance, React may delay it, and then update several components in a single pass. React does not guarantee that the state changes are applied immediately. setState() does not always immediately update the component. It may batch or defer the update until later.
- 把
setState
当作是请求更新组件,而不是立即更新组件。为了性能,React
会延迟更新,会把多个组件的更新放在一次操作里。React
不保证state
的改变会立刻发生。setState
并不总是立即更新组件。它可能会推后至批量更新。
那setStates什么时候是异步的呢?
React 文档给出这样的说法:
目前,在事件处理函数内部的
setState
是异步的那这玩意儿咋理解呢?官方文档也给出了解释:
例如,如果
Parent
和Child
在同一个click事件中都调用了setState
,这样就可以确保Child
不会被重新渲染两次。取而代之的是,React会将该state冲洗到浏览器事件结束的时候,在统一地进行更新。这种机制可以在大型应用中得到很好的提升。
那这样就可以解释为什么我的代码会出问题了,实际上我进行UI组件和容器组件拆分后,UI组件作为容器组件的子组件,在进行redux工作流程后,统一进行了state的更新,即上面最后一个函数,这就导致了异步的出现。
那既然明白了这个道理,我们就需要做一个小处理就ok了,不要在setState的更新函数中访问event变量
修改后的代码如下:
getInputChangeAction = (value) => ({
type: 'change_input_value',
value
})
handleInputChange(e) {
const value = e.target.value;
const action = getInputChangeAction(value);
store.dispatch(action);
}
handleStoreChange() {
this.setState(store.getState());
}
总结
其实最后只是做了一个很小的处理,写这么多也是想搞清楚为什么会出现这样一个情况。
另外最后React也给大家做了一个提醒。
setState的异步,这只是一个实现的细节,所以请不要直接依赖于这种机制。在以后的版本当中,React 会在更多的情况下静默地使用 state 的批更新机制。