reactjs - 如何在不重复触发的情况下更新 useEffect 中的卸载处理程序?

标签 reactjs react-hooks use-effect

今天,另一位开发人员向我提出了一个棘手的问题。她提出以下建议:

A.) 她想在模式关闭时触发一个事件。
B.) 她不希望事件在任何其他时间触发。
C.) 事件必须与组件的状态保持同步。

一个基本的例子是这样的:

const ModalComponent = () => {
    const [ eventData, setEventData ] = useState({ /* default data */ });
    useEffect(() => {
        return () => {
            // happens anytime dependency array changes
            eventFire(eventdata);
        };
    }, [eventData]);
   
    return (
       <>
         // component details omitted, setEventData used in here
       </>
    );
};

目的是当模式关闭时,事件触发。但是,用户与模式的交互会导致状态更新,从而更改 eventData 的值。这就引出了问题的核心:

  1. eventData 排除在 useEffect 依赖项数组之外会导致它仅在模式关闭时触发,但该值已过时。这是组件安装时的值。
  2. eventData 放在 useEffect 依赖数组中会导致事件反复触发,只要数据发生变化并且组件重新呈现和更新 useEffect

解决这个问题的方法是什么?您如何才能访问最新数据并仅在卸载时对其进行操作?

最佳答案

eventData 存储在 ref.

const [eventData, setEventData] = useState({ /* default data */ });
const ref = useRef();

ref.current = eventData;

useEffect(() => () => eventFire(ref.current), []);

这将使值始终保持最新,因为它不会被锁定在函数闭包中,并且无需在每次 eventData 更改时触发效果。

此外,您可以将此逻辑提取到自定义 Hook 中。

function useStateMonitor(state) {
  const ref = useRef();
  ref.current = state;
  return () => ref.current;
}

用法是这样的

const [eventData, setEventData] = useState({ /* default data */ });
const eventDataMonitor = useStateMonitor(eventData);

useEffect(() => () => eventFire(eventDataMonitor()), []);

这是一个 working example

关于reactjs - 如何在不重复触发的情况下更新 useEffect 中的卸载处理程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71655106/

相关文章:

过滤 map View 中的功能 React-Map-gl React Hooks

reactjs - React 中 Material UI DatePicker 中的最小和最大日期

javascript - 使用计算变量与 useState/useEffect 的结果

reactjs - RTK查询错误: could not find react-redux context value; please ensure the component is wrapped in a <Provider>

javascript - 在 React 中更新状态的优雅 ES6 方式

reactjs - Next.JS App Router, protected 路由,并隐藏布局闪烁

reactjs - 在 'antd' 库(Ant Design)中使用 select 时,所选选项显示值而不是标签

javascript - react ,页面刷新后使用useEffect丢失localStorage中保存的数据

javascript - React/Redux、useEffect/useSelector、陈旧的闭包和事件监听器

javascript - 如何在 useEffect 中调用 prop 函数?