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

如何实现自定义Hook使异步setData后立即获取最新data值

实现可同步获取最新值的自定义useState Hook

React内置的useState状态更新是异步批量执行的,所以调用setter后直接读取state变量只能拿到旧值。要实现调用自定义setter后立即获取最新状态,可通过以下几种方案实现:

方案一:让setter函数返回最新状态

修改自定义Hook,让setValue在更新状态后直接返回最新值,这样在异步调用后可以直接拿到结果:

import { useState, useCallback } from 'react';

const useCustomState = (initialValue) => {
  const [value, setValue] = useState(initialValue);
  
  const customSetValue = useCallback((newValue) => {
    // 兼容函数式更新的场景
    const updatedValue = typeof newValue === 'function' 
      ? newValue(value) 
      : newValue;
    setValue(updatedValue);
    return updatedValue;
  }, [value]);
  
  return [value, customSetValue];
};

// 使用示例
const [data, setData] = useCustomState(0);
useEffect(() => {
  const fn = async () => {
    const newData = await setData(1);
    console.log(newData); // 输出 1
  };
  fn();
}, []);

方案二:用Ref同步状态,提供获取最新值的方法

通过Ref维护一份与状态同步的副本,同时暴露一个getter函数,随时可以获取最新值:

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

const useCustomState = (initialValue) => {
  const [value, setValue] = useState(initialValue);
  const valueRef = useRef(value);
  
  // 组件更新时同步Ref与状态
  useEffect(() => {
    valueRef.current = value;
  }, [value]);
  
  const customSetValue = useCallback((newValue) => {
    const updatedValue = typeof newValue === 'function' 
      ? newValue(valueRef.current) 
      : newValue;
    // 先更新Ref,保证同步获取
    valueRef.current = updatedValue;
    setValue(updatedValue);
  }, []);
  
  const getCurrentValue = useCallback(() => valueRef.current, []);
  
  return [value, customSetValue, getCurrentValue];
};

// 使用示例
const [data, setData, getData] = useCustomState(0);
useEffect(() => {
  const fn = async () => {
    await setData(1);
    console.log(getData()); // 输出 1
  };
  fn();
}, []);

方案三:直接暴露同步状态的Ref

如果不想额外封装getter函数,也可以直接返回Ref,通过ref.current直接访问最新值(注意不要直接修改ref.current,状态更新仍通过setter完成):

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

const useCustomState = (initialValue) => {
  const [value, setValue] = useState(initialValue);
  const valueRef = useRef(value);
  
  useEffect(() => {
    valueRef.current = value;
  }, [value]);
  
  const customSetValue = useCallback((newValue) => {
    const updatedValue = typeof newValue === 'function' 
      ? newValue(valueRef.current) 
      : newValue;
    valueRef.current = updatedValue;
    setValue(updatedValue);
  }, []);
  
  return [value, customSetValue, valueRef];
};

// 使用示例
const [data, setData, dataRef] = useCustomState(0);
useEffect(() => {
  const fn = async () => {
    await setData(1);
    console.log(dataRef.current); // 输出 1
  };
  fn();
}, []);

核心原理

React的useState状态更新会触发组件重新渲染,新状态要等到下一次渲染才会生效。而Ref的更新是同步的,通过在自定义Hook中用Ref维护一份与状态实时同步的副本,就能在调用setter后立即获取到最新值,无需等待组件重新渲染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 12:20:11