You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS中useEffect无法获取更新后状态变量值的原因及解决

React状态与useEffect问题解答

1. 为什么刚调用setVal后,useEffect中val是undefined?

你初始化val时用了useState()(未传入初始值),所以val的初始值是undefined。组件第一次渲染时,第二个useEffect会因为依赖val(此时为undefined)触发,打印出undefined。而第一个useEffect是在组件挂载后执行的,它调用setVal("hello")属于异步状态更新,不会立刻改变当前渲染周期里的val值,所以第一次触发第二个useEffect时拿到的还是初始的undefined。

2. 第二个useEffect为什么触发两次?

你的判断是对的,触发两次的原因如下:

  • 第一次触发:组件初始挂载,val为初始的undefined,满足依赖触发条件;
  • 第二次触发:第一个useEffect执行setVal("hello"),val状态更新,组件重新渲染,依赖变化触发第二个useEffect。

如果是React 18+的开发环境严格模式,你会看到触发次数翻倍(打印undefined、hello、undefined、hello),这是React用来模拟组件卸载后重新挂载的过程,用于检测潜在bug,生产环境不会有这个行为。

3. 如何让第二个useEffect仅在val被第一次设置为有效值时触发一次?

可以用useRef标记是否已经执行过目标逻辑,结合对val有效值的判断,修改后的代码如下:

import React from 'react';
import { useState, useEffect, useRef } from 'react'

export function App(props) {
  const [val, setVal] = useState();
  const hasTriggered = useRef(false);

  useEffect(() => {
    setVal("hello");
  }, []);

  useEffect(() => {
    // 仅当val是有效值且从未触发过时执行逻辑
    if (val && !hasTriggered.current) {
      console.log("value: ", val);
      hasTriggered.current = true; // 标记为已触发
    }
  }, [val])

  return (
    <div className='App'>
    </div>
  );
}

这样只会在val第一次变为"hello"时打印一次,后续即使val再变化(如果有其他逻辑修改的话)也不会重复触发。

内容的提问来源于stack exchange,提问作者anon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 14:35:35