React更新器函数失效报错,常规setState却正常?(无法读取null的'name'属性)
解决React setState更新器函数中
Cannot read property 'name' of null的问题 嘿,我来帮你搞定这个问题!你遇到的这个报错其实是React合成事件的事件池化机制导致的,咱们一步步拆解来看:
问题根源
React为了优化性能,会对合成事件(就是你拿到的e对象)做池化处理:事件处理函数执行完毕后,React会清空这个事件对象的所有属性,然后把它放回事件池里复用。
- 当你用直接传对象的常规setState时,你是同步读取
e.target.name和e.target.value并创建新对象的——这时候事件处理函数还没执行完,事件对象还没被回收,所以一切正常。 - 但用更新器函数形式的setState时,这个更新函数是异步执行的(Fiber架构下React会批量处理状态更新),等它真正运行的时候,原来的事件对象
e已经被React回收了,e.target自然就变成null,也就会抛出你看到的报错。
两种解决方案
方案1:提前提取事件属性(推荐)
在调用setState之前,先把需要的name和value从事件对象里取出来存好,这样不管事件对象后续会不会被回收,咱们都有自己的副本可以用:
handleChange(e) { // 先提取需要的属性,保存到变量里 const { name, value } = e.target; this.setState((state, props) => ({ [name]: value })); }
方案2:取消事件池化
调用e.persist()方法,告诉React不要回收这个事件对象,这样异步执行更新器函数时还能访问到e.target:
handleChange(e) { // 阻止React回收该事件对象 e.persist(); this.setState((state, props) => ({ [e.target.name]: e.target.value })); }
不过这个方案不推荐作为首选,因为它会让事件对象无法被池化复用,多少会影响一点性能。
额外验证
你已经在构造函数里绑定了this,所以this的指向是没问题的,完全不用怀疑这方面的问题哦~
内容的提问来源于stack exchange,提问作者J. Hesters
相关产品推荐
相关产品推荐

