如何在闭包中获取最新数据?

const [currentZoom, setCurrentZoom] = useState<any>('Days') //缩放的状态

gantt.attachEvent('onEmptyClick', ()=>{
      console.log(currentZoom);
})

currentZoom为响应式数据,如何让打印结果为最新的

阅读 734
avatarAI BotBETA

要在闭包中获取最新的 currentZoom 状态,你可以使用 React 的 useRef 钩子来持有一个可变的引用,该引用会随着组件的重新渲染而持续更新。这是因为闭包(如事件处理函数)捕获的是变量在创建时的值,而不是在调用时的值。对于函数组件中的响应式数据,使用 useRef 可以确保你始终访问到最新的状态值。

以下是修改后的代码示例:

### 解决方案

你可以使用 `useRef` 来持有一个对 `currentZoom` 的引用,并在组件更新时更新这个引用。这样,在闭包中就可以通过这个引用来访问最新的 `currentZoom` 值。

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

function YourComponent() {
const [currentZoom, setCurrentZoom] = useState('Days'); // 缩放的状态
const currentZoomRef = useRef(currentZoom); // 创建一个对 currentZoom 的引用

useEffect(() => {

currentZoomRef.current = currentZoom; // 在每次 currentZoom 更新时,更新引用

}, [currentZoom]);

gantt.attachEvent('onEmptyClick', () => {

console.log(currentZoomRef.current); // 使用引用访问最新的 currentZoom 值

});

// 其他组件逻辑...

return (

// JSX 渲染...

);
}


### 解释

1. **`useRef` 钩子**:`useRef` 返回一个可变的对象,其 `.current` 属性被初始化为传递给 `useRef()` 的参数(`currentZoom` 的初始值)。这个对象在组件的整个生命周期内保持不变。

2. **`useEffect` 钩子**:`useEffect` 钩子用于在 `currentZoom` 状态改变时更新 `currentZoomRef.current` 的值。通过将 `currentZoom` 包含在 `useEffect` 的依赖数组中,每当 `currentZoom` 更新时,`useEffect` 内的回调函数就会执行。

3. **事件处理函数**:在 `gantt.attachEvent` 的回调函数中,通过 `currentZoomRef.current` 访问最新的 `currentZoom` 值。
2 个回答

用 useCallback:

const handleEmptyClick = useCallback(() => {
  console.log(currentZoom);
}, [currentZoom]); 

useEffect(() => {
  gantt.attachEvent('onEmptyClick', handleEmptyClick);
  return () => gantt.detachEvent('onEmptyClick', handleEmptyClick);
}, [handleEmptyClick]);

或者用 useRef:

const zoomRef = useRef(currentZoom);

useEffect(() => {
  zoomRef.current = currentZoom;
}, [currentZoom]);

useEffect(() => {
  gantt.attachEvent('onEmptyClick', () => {
    console.log(zoomRef.current); // 最新值
  });
}, []);
const [currentZoom, setCurrentZoom] = useState<string>('Days'); // 缩放的状态

gantt.attachEvent('onEmptyClick', () => {
  setCurrentZoom((prevZoom) => {
    console.log(prevZoom);
    return prevZoom;
  });
});

补充

优化后的版本

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

const [currentZoom, setCurrentZoom] = useState<string>('Days'); // 缩放的状态

const handleEmptyClick = useCallback(() => {
  setCurrentZoom((prevZoom) => {
    console.log(prevZoom);
    return prevZoom;
  });
}, [currentZoom]);

useEffect(() => {
  const eventId = gantt.attachEvent('onEmptyClick', handleEmptyClick);
  return () => {
    gantt.detachEvent(eventId);
  };
}, [handleEmptyClick]);
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏