React.js:如何等待子组件更新父组件refs状态后再执行后续更新?
问题解决方法
问题根源
你遇到的是React状态更新的闭包陷阱:updateRefs函数里用到的refs是函数创建时捕获的旧状态值。当Child1和Child2先后调用updateRefs时,两者都基于同一个未更新的refs对象做合并,后执行的Child2会覆盖Child1的修改,导致最终状态丢失Child1的ref。
解决方案:使用函数式更新
React的setState支持传入函数形式的参数,这个函数会接收当前最新的状态作为参数,确保每次更新都基于最新值,不会出现覆盖问题。修改updateRefs函数即可:
export default function Parent(props) { const ref1 = useRef(null); const ref2 = useRef(null); const ref3 = useRef(null); const [refs, setRefs] = useState({ "ref1": ref1, "ref2": ref2, "ref3": ref3, }); // 删掉无用的useEffect:useRef创建的ref引用永远不会变,这个effect只会执行一次,和初始化重复 // useEffect(() => { // updateRefs({ // "ref1": ref1, // "ref2": ref2, // "ref3": ref3, // }); // },[ref1, ref2, ref3]) function updateRefs(newRefs) { // 用函数式更新,基于最新的prevRefs合并 setRefs(prevRefs => ({ ...prevRefs, ...newRefs })); } return ( <div> <Child1 updateRefs={updateRefs} /> <Child2 updateRefs={updateRefs} /> </div> ) }
为什么这样有效?
- 函数式更新会让React在执行状态更新时,传入当前最新的
prevRefs,不管多少个子组件调用updateRefs,每次合并都是基于上一次更新后的最新状态。 - 删掉了原来的
useEffect:因为useRef创建的ref对象引用是固定不变的,依赖数组里的ref1/ref2/ref3永远不会触发effect重新执行,这个effect完全多余。
内容的提问来源于stack exchange,提问作者dns_nx
相关产品推荐
相关产品推荐

