如何使用React Hook更新父子组件传递的props 解决弹窗仅打开一次问题
问题根因
- 弹窗组件参数写法错误:React函数组件仅接收一个props对象作为唯一参数,你将参数拆成
(show: boolean, { callback })的写法,导致实际拿到的show是整个props对象,callback无法正常获取,关闭弹窗时父组件的show状态没有被正确更新。 - 弹窗内部维护独立状态,和父组件传入的
show属性不同步:内部showDialog仅在组件初始化时赋值一次,后续父组件传入的show变化不会同步到内部状态,导致状态不一致。
修复方案
第一步:修复弹窗组件(DialogTesting/ProgressDialog)逻辑
如果你的弹窗显隐完全由父组件控制,推荐做成受控组件,删除内部冗余状态,直接使用父组件传入的属性即可:
// 修正参数解构,所有属性都从第一个props参数里取 export default function DialogTesting({ show, callback }) { // 删除内部冗余的showDialog状态,直接用props传入的show控制显隐 return ( <View> <Dialog visible={show} title="Record New Progress" style={DIALOG} onClose={() => { // 直接调用父组件传入的回调更新父组件状态 callback() }} > {/* 其余弹窗内容保持不变 */} </Dialog> </View> ) }
如果确实需要在弹窗内部维护状态,需要添加监听同步父组件传入的show变化:
export default function DialogTesting({ show, callback }) { const [showDialog, doShow] = useState(show) // 添加useEffect同步父组件传入的show变化 useEffect(() => { doShow(show) }, [show]) return ( <View> <Dialog visible={showDialog} title="Record New Progress" style={DIALOG} onClose={() => { doShow(false) callback() }} > {/* 其余弹窗内容保持不变 */} </Dialog> </View> ) }
第二步:修复子组件拼写问题(可选,仅做代码规范优化)
将hanndleDialog改为正确拼写handleDialog,避免后续维护出错。
逻辑验证
修复后流程可以正常跑通:
- 点击触发区域:父组件
show变为true,弹窗接收show={true}直接展示 - 点击关闭弹窗:调用父组件传入的
callback,将父组件show改为false,弹窗隐藏/卸载 - 再次点击触发区域:父组件
show重新变为true,弹窗正常渲染展示,解决只能打开一次的问题
内容的提问来源于stack exchange,提问作者Lê Quốc Khánh
相关产品推荐
相关产品推荐

