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

React Native内部状态更新后事件监听器无法获取最新状态求助

问题排查与解决方案

核心原因:闭包导致的状态快照捕获问题

你的事件监听器(无论是DeviceEventEmitter还是NativeEventEmitter)在组件初始渲染时被创建,此时它捕获的是int_info的初始空数组快照。React状态更新会触发组件重渲染,但已创建的监听器不会重新生成,依然持有旧闭包中的状态值,因此始终拿不到更新后的数据。

解决方案1:使用useRef保存最新状态

useRef的.current属性是可变的,不受闭包限制,能始终保存最新的状态值:

export function TheComponent(){
  const [int_info, setInt_info] = useState([]);
  const [todos, setTodos] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
  // 创建ref存储最新的int_info
  const intInfoRef = useRef(int_info);

  // 每次int_info更新时同步更新ref
  useEffect(() => {
    intInfoRef.current = int_info;
  }, [int_info]);

  const getInfo = async (devicePk) => {
    setIsLoading(true);
    try {
      // 优化:统一用async/await替代混用写法,逻辑更清晰
      const response = await getDigest(devicePk);
      console.log("Digest: ", response.data);
      const newTodos = response.data.todos;
      const newInt_info = response.data.int_info;
      setInt_info(newInt_info);
      setTodos(newTodos);
      setIsLoading(false);
    } catch (error) {
      console.log("Error Digest: ", error, JSON.stringify(error));
      setIsLoading(false);
    }
  };

  // 事件监听器中通过ref获取最新状态
  useEffect(() => {
    const listener = NativeEventEmitter.addListener('your-event-name', () => {
      console.log("最新int_info: ", intInfoRef.current);
      // 此处可正常使用更新后的数据
    });

    return () => {
      listener.remove(); // 组件卸载时清理监听器,避免内存泄漏
    };
  }, []); // 依赖项为空,仅挂载一次监听器
}

解决方案2:监听状态变化,动态重建监听器

通过useEffect监听int_info的变化,每次状态更新时重新创建监听器,确保监听器捕获最新状态:

export function TheComponent(){
  const [int_info, setInt_info] = useState([]);
  const [todos, setTodos] = useState([]);
  const [isLoading, setIsLoading] = useState(true);

  const getInfo = async (devicePk) => {
    setIsLoading(true);
    try {
      const response = await getDigest(devicePk);
      console.log("Digest: ", response.data);
      const newTodos = response.data.todos;
      const newInt_info = response.data.int_info;
      setInt_info(newInt_info);
      setTodos(newTodos);
      setIsLoading(false);
    } catch (error) {
      console.log("Error Digest: ", error, JSON.stringify(error));
      setIsLoading(false);
    }
  };

  // 依赖项加入int_info,状态更新时自动重建监听器
  useEffect(() => {
    const listener = NativeEventEmitter.addListener('your-event-name', () => {
      console.log("最新int_info: ", int_info);
    });

    return () => {
      listener.remove();
    };
  }, [int_info]);
}

额外优化提示

  • 避免async/await与.then()混用,统一使用async/await可提升代码可读性与调试效率。
  • 组件卸载时必须移除事件监听器,防止内存泄漏,上述两个方案均已包含清理逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 01:27:47