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

React中useEffect清理函数内的Ref数组为何全为null?

问题原因分析

你的代码出现这个问题有两个核心原因:

  1. React执行顺序影响:

    • 组件挂载时,useEffect的回调会在DOM挂载完成、ref回调执行之后才触发,但你只是把localRefs指向了refs.current数组的引用,并没有保存数组元素的快照。
    • 组件卸载时,React会先调用所有ref回调并传入null(把refs.current数组的每个元素设为null),之后才执行useEffect的清理函数。此时localRefs因为和refs.current指向同一个数组,打印出来自然是包含三个null的数组。
  2. 引用类型的特性:
    refs.current是数组(引用类型),你赋值给localRefs的是数组的引用而非元素副本。后续数组内容的修改会直接反映在localRefs上。

解决方案

要在卸载阶段获取到卸载前的DOM节点,需要在组件挂载完成后保存一份refs元素的快照,而非数组引用:

const refs = useRef([]);

useEffect(() => {
  // 组件挂载完成后,refs.current已被ref回调赋值,此时创建元素快照
  const snapshotRefs = [...refs.current];
  return () => {
    console.log("unmounting", snapshotRefs);
  };
}, []);

return (
  <>
    <div ref={(el) => { refs.current[0] = el; }}></div>
    <div ref={(el) => { refs.current[1] = el; }}></div>
    <div ref={(el) => { refs.current[2] = el; }}></div>
  </>
);

修改后,snapshotRefs是挂载完成后DOM节点的副本,卸载时即使原数组被设为null,快照也不受影响,能正确打印出卸载前的DOM元素。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 17:36:10