React Hooks中可访问当前状态的ComponentWillUnmount等效实现方案
解决组件卸载时获取最新状态且仅触发一次的问题
这个问题的核心是闭包陷阱:当你给useEffect传空依赖数组时,清理函数会捕获初始渲染时的count值,所以卸载时打印的永远是0;但如果把count加入依赖,每次count变化都会触发useEffect的清理和重新执行,不符合“仅卸载时触发一次”的要求。
这里有个完美的解决方案——用useRef跟踪状态的最新值,同时保持useEffect的依赖为空数组:
import * as React from "react"; import "./styles.css"; import { useState, useEffect, useRef } from "react"; const Counter = () => { const [count, setCount] = useState(0); // 创建ref来保存最新的count值 const countRef = useRef(count); // 每次count更新时,同步更新ref的current值 useEffect(() => { countRef.current = count; }, [count]); // 这个useEffect仅在组件卸载时执行清理函数 useEffect(() => { return () => { // 这里访问ref.current就能拿到最新的count值 console.log("Count was " + countRef.current + " when counter disappeared!"); }; }, []); const handleClick = () => { setCount(count + 1); }; return <button onClick={handleClick}>{count}</button>; }; export default function App() { const [showCounter, setShowCounter] = useState(true); const handleClick = () => { setShowCounter(!showCounter); }; return ( <div className="App"> <button onClick={handleClick}>Show/Hide counter</button> {showCounter && <Counter />} </div> ); }
原理说明:
useRef的.current属性是可变的,而且不会被React的闭包机制锁定——每次count更新时,我们通过第二个useEffect同步更新countRef.current,确保它始终指向最新的状态值。- 负责清理的
useEffect依赖数组为空,所以它只会在组件挂载时执行一次,对应的清理函数只会在组件卸载时触发一次,完全符合你的需求。
这种方式既保证了清理函数能拿到最新状态,又严格控制了仅在卸载时执行一次,完美解决你的矛盾点。
内容的提问来源于stack exchange,提问作者Michael Krakhofer
相关产品推荐
相关产品推荐

