React中如何正确实现子组件向父组件传值?开关状态不同步如何修复
问题根源
你的代码存在两套完全独立的显隐状态,没有做同步:
- Parent 用
isChildVisible状态控制是否渲染 Child 组件 - Child 内部自己维护了
isClosePopup状态控制内部内容是否展示
当你在 Child 内部点击关闭按钮时,仅修改了 Child 自己的内部状态,Parent 的 isChildVisible 仍为 true。此时你点击 Parent 的触发按钮,只会先把 isChildVisible 改为 false,界面上没有任何可见变化,给人的错觉就是「无法再次打开」,本质是状态冗余、不同步导致的逻辑异常。
修复方案
完全可以统一用一个 useState 管理状态,遵循状态提升的原则,把显隐状态完全交给 Parent 维护,Child 只通过 props 接收关闭的回调方法即可,不需要自己再维护内部的显隐状态。
重写后的代码如下:
import { useState } from 'react'; export const Parent = () => { const [isChildVisible, setChildVisible] = useState(false); return ( <> <span className="link" onClick={() => { setChildVisible(!isChildVisible); }} > Click </span> {/* 把关闭方法通过props传给Child */} {isChildVisible && <Child onClose={() => setChildVisible(false)} />} </> ); }; export const Child = ({ onClose }) => { return ( <StyledChild> <span onClick={onClose} > X </span> Content </StyledChild> ); };
如果后续需要让 Child 支持更灵活的受控调用,也可以把显隐状态和修改方法都通过 props 传入,做成标准的受控组件:
// Parent 调用示例 {/* <Child visible={isChildVisible} onVisibleChange={setChildVisible} /> */} export const Child = ({ visible, onVisibleChange }) => { if (!visible) return null; return ( <StyledChild> <span onClick={() => onVisibleChange(false)} > X </span> Content </StyledChild> ); };
内容的提问来源于stack exchange,提问作者kahjuksEi
相关产品推荐
相关产品推荐

