React的setState方法为什么有时候不生效?

阅读时长 5 分钟读完

在 React 中,组件状态的改变是通过 setState 方法实现的。然而有时候我们会发现,调用 setState 方法后,组件的状态并没有发生改变,这时候我们就需要了解造成这种情况的原因。

原因一:异步更新

React 中的 setState 方法是异步更新的,也就是说,我们不能保证 setState 方法何时执行完毕,因为它可能等待其他代码执行完毕后再去执行。这可能导致在我们执行 setState 方法后,立即去访问 state 中的变量会得到旧的值,而不是更新之后的值。例如:

解决这个问题一般有两种方法:

  1. setState 方法的回调函数中去访问 state 的更新值,因为在回调函数中可以保证 state 已经更新。例如:
  1. 使用 setTimeout 去等待一段时间后再去访问 state 的更新值。例如:

当然,如果你使用了 React.StrictMode ,你会发现在控制台中会出现警告,提示我们不能再 setTimeout 中去访问 state,这是 React 为了安全起见设定的。不过,如果你觉得不使用 React.StrictMode 也没关系,可以在 setTimout 中添加 try-catch 语句把警告消除。

原因二:同步更新

除了异步更新外,可能还存在同步更新的情况。在处理一些复杂计算的场景下,你只需要在函数中调用几次 setState,而虽然调用了 setState,但在函数结束前连同组件一起卸载,这个时候虽然我们调用了 setState ,但它已经不会起到任何效果。这种情况下可以使用 isMounted 的方式去判断组件是否还在页面上渲染,如果组件已经 unmount,就没有必要再去更新组件状态了。

原因三:使用不当

在 setState 的调用过程中还有一些使用不当的情况会导致无更新,例如,使用不正确的 state 引用,或者把 shouldComponentUpdate 强制设为 false,等等。

使用不正确的 state 引用

在 React 中有些情况下同时存在两个不同的 state,这时候可能会发生使用错误的情况。例如:

这段代码的本意是让 count 加 1 再减 1,但实际上它会让 count 减 1,因为第二个 setState 会使用第一个 setState 引用时的旧值减去 1。

我们可以改成以下代码:

这样就避免了使用不正确的 state 引用了。

shouldComponentUpdate 被强制设为 false

shouldComponentUpdate 是 React 中用来控制组件是否重新渲染的方法,它默认返回 true,表示组件每次 setState 时都会重新渲染。但当我们将 shouldComponentUpdate 的返回值设置为 false 时,组件就不会重新渲染。这样,我们的 setState 就会无效了。

总结

  • 在 React 中,setState 方法是异步更新的,不能保证在调用之后立即更新。
  • 在 setState 方法的回调函数中去访问 state 的更新值,或者使用 setTimeout 去等待一段时间后再去访问 state 的更新值。
  • 当需要在一些复杂计算的场景下进行 setState 调用时,可以使用 isMounted 判断组件是否还在页面上渲染。
  • 使用不正确的 state 引用时可能会导致 setState 无效。
  • 将 shouldComponentUpdate 的返回值设置为 false 时,组件就不会重新渲染,这样 setState 就会无效了。

希望这篇文章可以帮助你更好的理解 React 中 setState 方法无效的原因,并提供一些建议来解决这样的问题。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/645c3ad3968c7c53b0e81543

纠错
反馈