React扫码触发的模态框点击关闭后立即复现问题求助
问题根源
- 父子组件的
useEffect均未声明依赖数组,每次组件重渲染都会重复执行内部逻辑 - 扫码后父组件的
flag状态始终为true,子组件每次重渲染都会触发useEffect将内部open重置为true,导致关闭后立刻重新弹出 - 子组件关闭事件仅修改了内部状态,未同步修改父组件的控制状态,父子状态不同步
- 父组件扫码后
data值未清空,会重复触发接口请求逻辑
修复方案
1. 修改父组件 QrScanner
- 给
useEffect添加[data]依赖,避免重复执行请求逻辑 - 新增关闭模态框的回调方法,同步重置
flag和data状态 - 将关闭回调作为prop传给子组件
修改后代码:
const QrScanner = () => { const [data, setData ] = useState(''); const [flag, setFlag] = useState(false); const [title, setTitle] = useState(''); const history = useHistory(); // 新增关闭模态框方法 const handleCloseModal = () => { setFlag(false); setData(''); // 清空扫描数据,避免重复触发请求 }; // 添加依赖数组 [data],仅data变化时执行 useEffect(() => { if(data === '') { return; } if (Number.isInteger(parseInt(data))) { axios.get('/api/qrcodescanner/ean/' + data) .then(res => { if (res.data.title != false) { setFlag(true); setTitle(res.data.title); } else { setData('Sorry, Wrong barcode!'); } }) } }, [data]) return ( <> <BarcodeScannerComponent width={500} height={500} onUpdate={(err, result) => { if (result) { setData(result.text); } }} /> <p className="modal-result-show">{data}</p> {/* 传入关闭回调 */} <ResponseModal flag={flag} data={data} title={title} onClose={handleCloseModal}/> </> ); }
2. 修改子组件 ResponseModal
推荐直接用父组件传入的flag控制模态框显示,不需要额外维护内部open状态,避免状态重复,修改后代码:
const ResponseModal = (props) => { const closeIcon = ( <svg fill="black" width="28" height="28" viewBox="0 0 36 36" data-testid="close-icon"><path d="M28.5 9.62L26.38 7.5 18 15.88 9.62 7.5 7.5 9.62 15.88 18 7.5 26.38l2.12 2.12L18 20.12l8.38 8.38 2.12-2.12L20.12 18z"></path></svg> ); const {flag, title, onClose} = props; return ( <> <Modal open={flag} onClose={onClose} center closeIcon={closeIcon} modalId="response-modal"> <div className="qr-modal-header-stock"> <h5>Enter stock</h5> <p>{title}</p> </div> </Modal> </ > ); }
如果你需要保留子组件内部的open状态做额外控制,修改如下:
const ResponseModal = (props) => { const closeIcon = ( <svg fill="black" width="28" height="28" viewBox="0 0 36 36" data-testid="close-icon"><path d="M28.5 9.62L26.38 7.5 18 15.88 9.62 7.5 7.5 9.62 15.88 18 7.5 26.38l2.12 2.12L18 20.12l8.38 8.38 2.12-2.12L20.12 18z"></path></svg> ); const {flag, title, onClose} = props; const [open, setOpen] = useState(false); const onCloseModal = () => { setOpen(false); onClose(); // 调用父组件关闭回调 }; // 添加依赖数组 [flag],仅flag变化时执行 useEffect(() => { if(flag) { setOpen(true); } }, [flag]) return ( <> <Modal open={open} onClose={onCloseModal} center closeIcon={closeIcon} modalId="response-modal"> <div className="qr-modal-header-stock"> <h5>Enter stock</h5> <p>{title}</p> </div> </Modal> </ > ); }
内容的提问来源于stack exchange,提问作者Áron Pop Adorján
相关产品推荐
相关产品推荐

