I have a modal which opens up when I scan a qr Code. After this I set a props to true which tells my Responsemodal to open up. Problem is, I cannot close because this prop is read-only in child component.
Here is my code:
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, data, title} = props;
const [open, setOpen] = useState(false);
const onCloseModal = () => setOpen(false);
useEffect(() => {
if(flag == true) { <--- qr code scanned, this trigger my ResponseModal to open up but it remains true
setOpen(true);
}
})
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>
</ >
);
}
And my parent component:
const QrScanner = () => {
const [data, setData ] = useState('');
const [flag, setFlag] = useState(false);
const [title, setTitle] = useState('');
const history = useHistory();
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!');
}
})
}
})
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}/>
</>
);
}
Even though I set open to false onClose, it dissapears and appears right after, Any thoughts what i'm missing?
CodePudding user response:
You forgot add dependencies in useEffect
. Just add flag
to dependencies array to make sure it only call when flag change
useEffect(() => {
if(flag == true) { <--- qr code scanned, this trigger my ResponseModal to open up but it remains true
setOpen(true);
}
}, [flag])
CodePudding user response:
I see you need to expose something back to the parent, there're couple of ways.
open
state relocated to the parent.
const ResponseModal = ({ open, setOpen }) => {
// currently you use a state, but instead
// relocate this state to the parent
}
const QrScanner = () => {
const [open, setOpen] = useState(false)
return <ResponseModal open={open} setOpen={setOpen} />
}
Basically ask your parent to manage the modal.
listening to the on
state
If you think the above approach is too heavy, because you already have a very nice Modal component. We could only build a on
flag.
const ResponseModal = ({ on }) => {
const [open, setOpen] = useState(on)
useEffect(() => {
setOpen(on)
}, [on])
}
const QrScanner = () => {
const [on, setOn] = useState(false)
return <ResponseModal on={on} />
}
This is a trick to make sure on
can drive open
when changed. In your parent you can just call setOn(false)
.
I didn't notice you are already using a flag
, so that is the on
.