React中使用useState时状态更新不生效的原因及解决方法

 更新时间:2025年12月19日 09:49:52   作者:小明记账簿  
在使用 React 的 useState 钩子时,有时我们会遇到通过 set 方法更新状态后界面没有相应变化的情况,这可能是由于一些常见的问题导致的,本文将详细分析这些可能的原因,并提供相应的解决方案,需要的朋友可以参考下

一、正常情况

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。

问题原因

  1. 组件初始化时, count 状态被设置为1
  2. useEffect 钩子只在组件首次渲染时运行一次(因为依赖数组为空 [] )
  3. 在 useEffect 中, onWindowKeyDown 函数创建了一个闭包,它捕获了当时的 count 值(即初始值1)
  4. 每次按下键盘时,调用的是这个闭包函数,它总是引用初始的 count 值(1)
  5. 因此,每次调用 setCount(count + 1) 实际上都是执行 setCount(1 + 1) ,导致 count 永远只会被设置为2
  6. 即使 state 更新导致组件重新渲染,由于 useEffect 的依赖数组为空,它不会再次运行,闭包中的 count 值也不会更新

如何解决这个问题,不要慌,经过我不懈的研究,终于解决了,我们可以使用函数形式来更新状态。这样可以确保我们总是在最新的状态基础上进行更新。

示例代码

const onWindowKeyDown = () => {
  setCount(prevCount => prevCount + 1) // 使用函数形式
}

在这种形式下,setCount 接收一个函数作为参数,该函数的参数是当前的状态值 prevCount,函数的返回值就是新的状态值。这种方式可以保证获取到的是最新的状态值。

以上就是React中使用useState时状态更新不生效的原因及解决方法的详细内容,更多关于React使用useState状态更新不生效的资料请关注脚本之家其它相关文章!

相关文章

  • React 中hooks之 React.memo 和 useMemo用法示例总结

    React 中hooks之 React.memo 和 useMemo用法示例总结

    React.memo是一个高阶组件,用于优化函数组件的性能,通过记忆组件渲染结果来避免不必要的重新渲染,合理使用React.memo和useMemo可以显著提升React应用的性能,本文介绍React 中hooks之 React.memo 和 useMemo用法总结,感兴趣的朋友一起看看吧
    2025-01-01
  • react配合antd组件实现的管理系统示例代码

    react配合antd组件实现的管理系统示例代码

    这篇文章主要介绍了react配合antd组件实现的管理系统示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • React引入css的几种方式及应用小结

    React引入css的几种方式及应用小结

    这篇文章主要介绍了React引入css的几种方式及应用小结,操作styled组件的样式属性,可在组件标签上定义属性、也可以通过attrs定义属性,本文通过实例代码介绍的非常详细,需要的朋友可以参考下
    2024-03-03
  • react学习笔记之state以及setState的使用

    react学习笔记之state以及setState的使用

    这篇文章主要介绍了react学习笔记之state以及setState的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • 详解如何封装和使用一个React鉴权组件

    详解如何封装和使用一个React鉴权组件

    JavaScript 和 React 提供了灵活的事件处理机制,特别是通过利用事件的捕获阶段来阻止事件传播可以实现精细的权限控制,本文将详细介绍这一技术的应用,并通过实践案例展示如何封装和使用一个 React 鉴权组件,需要的可以参考下
    2024-03-03
  • React中useRef与useState的使用与区别

    React中useRef与useState的使用与区别

    本文介绍了React中两个常用的钩子useRef和useState,包含比较它们的功能并提供示例来说明它们的用法,具有一定的参考价值,感兴趣的可以了解一下
    2024-11-11
  • React useCallback使用教程

    React useCallback使用教程

    useCallback是react中比较重要的一个hook,useCallback 用来返回一个函数,在父子组件传参或者通用函数封装中,起到举足轻重的作用
    2023-01-01
  • react中antd文本框限制输入中文方式

    react中antd文本框限制输入中文方式

    这篇文章主要介绍了react中antd文本框限制输入中文方式详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • 深入分析React源码中的合成事件

    深入分析React源码中的合成事件

    合成事件不是浏览器本身触发的事件,自己创建和触发的事件。本文将从源码角度带大家一起深入了解下React中的合成事件,需要的可以参考一下
    2022-11-11
  • 详解React ISR如何实现Demo

    详解React ISR如何实现Demo

    这篇文章主要为大家介绍了React ISR如何实现Demo详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07

最新评论