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
相关产品推荐
相关产品推荐

