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

React函数组件中如何在自定义函数内获取更新后的state值?

问题核心

React的setState是异步更新状态的,在同一个函数执行栈里,状态不会立刻生效。你在useEffect中调用GetData()后马上执行ShowData(data),此时data还是useEffect闭包捕获的初始值[];而组件外部的console.log(data)是在状态更新触发组件重新渲染后执行的,所以能拿到最新的[1,2,3]。

解决方法

方法一:直接传递新数据给ShowData

既然在GetData里已经明确要设置的新数据,直接在setData之后把这个值传给ShowData即可,省去依赖状态的麻烦:

function Foo() {
 const [data, setData] = useState([]);
 
 const GetData = () => {
  const newData = [1, 2, 3];
  setData(newData);
  ShowData(newData); // 直接传入刚定义的新数据
 }
 
 const ShowData = (data) => {
  if(data)
     console.log(data);
}

useEffect( () => {
  GetData();
},[]);

console.log(data);
return (
<>
 <h2>Hello world ! </h2>
</>
)}

方法二:用useEffect监听data的变化

新增一个useEffect,将data作为依赖项,每当data更新时自动触发ShowData:

function Foo() {
 const [data, setData] = useState([]);
 
 const GetData = () => {
  setData([1, 2, 3]);
 }
 
 const ShowData = (data) => {
  if(data)
     console.log(data);
}

// 仅在组件初始化时调用GetData
useEffect( () => {
  GetData();
},[]);

// 监听data的变化,状态更新时执行ShowData
useEffect( () => {
  ShowData(data);
},[data]); // 依赖数组添加data,确保状态变化时触发

console.log(data);
return (
<>
 <h2>Hello world ! </h2>
</>
)}

方法三:用useRef保存最新状态(适配复杂异步场景)

如果你的业务场景涉及定时器、异步回调等复杂逻辑,需要随时获取最新状态,可以用useRef来同步保存最新的data值:

function Foo() {
 const [data, setData] = useState([]);
 const dataRef = useRef(data);
 
 // 每次data更新时同步更新ref的current值
 useEffect(() => {
  dataRef.current = data;
 }, [data]);
 
 const GetData = () => {
  setData([1, 2, 3]);
 }
 
 const ShowData = () => {
  if(dataRef.current)
     console.log(dataRef.current); // 从ref中获取最新状态
}

useEffect( () => {
  GetData();
  // 由于setState异步,这里用setTimeout确保能拿到更新后的ref值
  setTimeout(() => {
    ShowData();
  }, 0);
},[]);

console.log(data);
return (
<>
 <h2>Hello world ! </h2>
</>
)}

日常开发中,方法一和方法二足以解决绝大多数类似问题,可根据实际业务需求选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 02:40:30