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

React中Ref回调的clean up函数重渲染时未执行问题求助

React Ref回调Cleanup未执行的解决方法

你遇到的问题根源是误解了ref回调的cleanup机制:React并不会执行ref回调返回的函数,而是通过向回调传入null来触发cleanup逻辑。你当前代码里返回的() => console.log('finish')永远不会被调用,自然看不到预期的输出。

要实现「回调更新时执行cleanup」的需求,只需把cleanup逻辑放到ref回调内部,根据传入的node是否为null来区分挂载/cleanup操作:

方法1:内联回调(每次渲染都触发cleanup)

每次组件重渲染时,内联函数会生成新的实例,React会先调用旧回调传入null(执行cleanup),再调用新回调传入DOM节点(执行挂载逻辑):

import React, { useState } from 'react';

export default function App() {
  const [x, setX] = useState(2);

  return (
    <>
      <p ref={(node) => {
        if (node) {
          // 挂载逻辑
          console.log('start');
        } else {
          // Cleanup逻辑
          console.log('finish');
        }
      }}>{x}</p>
      <button onClick={() => setX(x + 1)}>hello</button>
    </>
  );
}

点击按钮后,控制台会依次输出finish和start,符合你的预期。

方法2:用useCallback缓存回调(按需触发cleanup)

如果不想每次渲染都生成新回调,可通过useCallback缓存回调,仅当依赖项变化时更新回调,此时React同样会触发cleanup:

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

export default function App() {
  const [x, setX] = useState(2);

  const refCallback = useCallback((node) => {
    if (node) {
      console.log('start');
    } else {
      console.log('finish');
    }
  }, [x]); // 当x变化时,回调更新,触发cleanup

  return (
    <>
      <p ref={refCallback}>{x}</p>
      <button onClick={() => setX(x + 1)}>hello</button>
    </>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 02:25:05