setState的一个Synthetic Event Warning

今天使用React时遇到一个警告:javascript

clipboard.png

Warning: This synthetic event is reused for performance reasons. If you're seeing this, you're accessing the property target on a released/nullified synthetic event. This is set to null. If you must keep the original synthetic event around, use event.persist(). See https://fb.me/react-event-poo... for more information.

查看文档解释:java

The SyntheticEvent is pooled. This means that the SyntheticEvent object will be reused and all properties will be nullified after the event callback has been invoked. This is for performance reasons. As such, you cannot access the event in an asynchronous way.

SyntheticEvent 对象是经过合并获得的。 这意味着在事件回调被调用后,SyntheticEvent 对象将被重用而且全部属性都将被取消。这是出于性能缘由。所以,您没法以异步方式访问该事件。react

意思就是说我访问event.target时处于异步操做中。个人代码是:app

handleTitleChange: React.ChangeEventHandler<HTMLInputElement> = (event) => {
    this.setState((prevState) => ({
        collection: {
            title: event.target.value,
            content: prevState.content
        }
    }));
}

看了不少遍没发现哪里有异步操做,没办法只好加event.persist()先解决掉警告:异步

handleTitleChange: React.ChangeEventHandler<HTMLInputElement> = (event) => {
    event.persist();
    this.setState((prevState) => ({
        collection: {
            title: event.target.value,
            content: prevState.content
        }
    }));
}

可是,我忽然回想起setState并不保证是同步的:async

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并不老是当即更新组件。它可能会推后至批量更新。函数

因此,在个人这段代码中显然setState是异步的,由于Event Polling咱们不能在setState的更新函数中访问event变量。既然找到了缘由,解决方法就有了:性能

不要在setState的更新函数中访问event变量:this

handleTitleChange: React.ChangeEventHandler<HTMLInputElement> = (event) => {
    const val = event.target.value;
    this.setState((prevState) => ({
        collection: {
            title: val,
            content: prevState.content
        }
    }));
}

或者若是不须要prevState的话:spa

handleTitleChange: React.ChangeEventHandler<HTMLInputElement> = (event) => {
    this.setState({
        collection: {
            title: event.target.value,
            content: this.state.content
        }
    });
}
相关文章
相关标签/搜索