写这篇文章的初衷是在项目当中遇到了类似下面的一个问题:
function App() {const onChange = (e) => {setTimeout(() => {console.log(e.target.value)}, 1000)}return (<div className="App"><input onChange={onChange}/></div>);}
这段代码设计的初衷是利用延迟一秒打印 input 的值,结果在React 16当中会报错。查阅文档以后得知,原因是React 16使用的是合成事件(SyntheticEvent)而且配有事件池,为了节约内存,同一事件有可能会被重复利用,在相应的回调函数被调用后,当前合成事件对象会被重置,其中target会被重置为 undefined 。
为了解决这一问题,React 16为每个事件对象提供了一个 persist 方法,调用它以后对应事件就不会被回收。
function App() {const onChange = (e) => {e.persist()setTimeout(() => {console.log(e.target.value)}, 1000)}return (<div className="App"><input onChange={onChange}/></div>);}
值得一提的是,在最新的React 17中,事件池机制已经被取消,理由是这个机制对于现代浏览器来说并不能提高性能。所以以后我们无需调用 e.persist 就可以放心使用 e.target 了。同时为了兼容以前的代码, e.persist 得到了保留,只不过这已经是一个空函数,没有任何作用了。
