React中使用useState时状态更新不生效的原因及解决方法
一、正常情况
useState 返回的 set 方法是更新状态的关键。我们需要确保在适当的地方调用它,通常是在事件处理函数或异步操作的回调中。
示例代码
import React, { useState, useEffect } from 'react'
const MyComponent = () => {
const [count, setCount] = useState(1)
const increment = () => {
setCount(count + 1)
}
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
</div>
)
}
export default MyComponent
在这个例子中,当点击按钮时,increment 函数会调用 setCount 来更新 count 的值,从而触发组件重新渲染。
二、不正常情况
再看下面的例子,我想监听键盘的按下事件,每按一次加1,按照这个思路执行,代码没有任何问题,看是真会如愿以偿吗?
import React, { useState, useEffect } from 'react'
const MyComponent = () => {
const [count, setCount] = useState(1)
useEffect(() => {
// 监听全局键盘事件
window.addEventListener('keydown', onWindowKeyDown)
return () => {
// 移除全局键盘事件
window.removeEventListener('keydown', onWindowKeyDown)
}
}, [])
const onWindowKeyDown = () => {
console.log('keyDown:', count)
setCount(count + 1)
}
return (
<div>
<p>Count: {count}</p>
</div>
)
}
export default MyComponent
通过控制台查看,无论执行多少次count始终都是1,setCount(count + 1)始终都是2。

问题原因
- 组件初始化时, count 状态被设置为1
- useEffect 钩子只在组件首次渲染时运行一次(因为依赖数组为空 [] )
- 在 useEffect 中, onWindowKeyDown 函数创建了一个闭包,它捕获了当时的 count 值(即初始值1)
- 每次按下键盘时,调用的是这个闭包函数,它总是引用初始的 count 值(1)
- 因此,每次调用 setCount(count + 1) 实际上都是执行 setCount(1 + 1) ,导致 count 永远只会被设置为2
- 即使 state 更新导致组件重新渲染,由于 useEffect 的依赖数组为空,它不会再次运行,闭包中的 count 值也不会更新
如何解决这个问题,不要慌,经过我不懈的研究,终于解决了,我们可以使用函数形式来更新状态。这样可以确保我们总是在最新的状态基础上进行更新。
示例代码
const onWindowKeyDown = () => {
setCount(prevCount => prevCount + 1) // 使用函数形式
}
在这种形式下,setCount 接收一个函数作为参数,该函数的参数是当前的状态值 prevCount,函数的返回值就是新的状态值。这种方式可以保证获取到的是最新的状态值。
以上就是React中使用useState时状态更新不生效的原因及解决方法的详细内容,更多关于React使用useState状态更新不生效的资料请关注脚本之家其它相关文章!
相关文章
react函数组件useState异步,数据不能及时获取到的问题
这篇文章主要介绍了react函数组件useState异步,数据不能及时获取到的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-08-08
react koa rematch 如何打造一套服务端渲染架子
这篇文章主要介绍了react koa rematch 如何打造一套服务端渲染架子,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2019-06-06


最新评论