React两个同父级子组件切换时useCallback仅生效一次问题排查
问题原因
你的问题是useCallback的闭包陷阱导致的:
- 你给
useCallback的依赖数组传入了空数组[],这会让这个回调函数只会在组件首次渲染时创建一次,之后永远复用首次创建的版本 - 首次渲染时
status的值是true,这个值被闭包捕获后就一直固定在你缓存的callback函数里,永远不会更新 - 第一次调用回调时
!status是false,status成功更新为false,组件切换到<Documents />;但后续再调用回调时,闭包里的status还是旧的true,所以每次执行setQuotestatus(!status)都是把值设置为false,自然不会触发组件切回。
修复方案
方案1:给useCallback添加正确的依赖项
把status加入useCallback的依赖数组,这样每次status变化时都会生成新的回调函数,闭包里就能拿到最新的status值:
const callback = useCallback((Items, quotation) => { setItems(Items); setQuotation(quotation); console.log(status) setQuotestatus(!status); console.log(quotation, status); }, [status]); // 把status加入依赖
方案2:使用setState的函数式更新写法(更推荐)
如果你不需要在回调里读取最新的status做其他逻辑,直接用函数式更新状态的写法,就不需要依赖status,也能避免闭包问题:
const callback = useCallback((Items, quotation) => { setItems(Items); setQuotation(quotation); // 函数式更新,React会自动传入最新的status值 setQuotestatus(prevStatus => !prevStatus); }, []); // 依赖数组还是空,不需要加status
这种写法不需要跟踪status的变化,性能更好,也不会出现闭包相关的状态错误。
内容的提问来源于stack exchange,提问作者Ameen NA
相关产品推荐
相关产品推荐

