I want to create a flexible modal wrapper where I can put interactive components within. In this case, I want to put an input into the modal that would affect the overall state of the form.
The form:
const [formInfo, setFormInfo] = useState({});
const [modalMetadata, setModalMetadata] = useState({});
const [modalContents, setModalContents] = useState({});
const [modalShow, setModalShow] = useState(false);
...
return <ModalWrapper modalIsOpen={modalShow} closeModal={() => {setModalShow(false)}} contents={modalMetadata}>
{modalContents}
</ModalWrapper>
<button onClick={
setModalShow(true);
setModalMetadata({
contentLabel: "",
title: "Are you sure?",
buttons: [
{
onClick: () => setModalShow(false),
content: "Cancel"
},
{
onClick: () => submitForm(),
content: "Confirm"
}
],
})}
setModalContents(<div><h4>blahblahblah</h4>
{inputTitles.map((k) => <div key={"field-"+ k}>
<div>
<input
type='text'
onChange={i => {
console.log(i.target.value);
console.log(formInfo)
console.log({...formInfo, ["field-" + k]: i.target.value})
setFormInfo( formInfo => {return {...formInfo, ["field-" + k]: i.target.value}})
}}
/>
<span></span>
</div>
<label>${k}</label>
</div>)}
</div>);
}>
The wrapper:
import Modal from 'react-modal';
export default function ModalWrapper({ modalIsOpen, closeModal, contents, children }) {
return (
<div>
<Modal
isOpen={modalIsOpen}
onRequestClose={closeModal}
contentLabel={contents.contentLabel}
>
<h2>{contents.title}</h2>
{children}
<div>
{(contents?.buttons ?? []).map((i, idx) => <button className={i.className} key={"button-" + idx} onClick={i.onClick}>{i.content}</button>) }
</div>
</Modal>
</div>
);
}
(CSS and irrelevant variables removed for brevity)
While most the debugging console statements are returning expected values and the buttons are working as planned, I’ve noticed that formInfo
is not being updated. What is the reason behind setFormInfo
not working as expected in the modal contents?
I looked online and I found multiple examples of this mechanic working (1, 2), where they would pass a React hook through the child of another component, but I couldn’t replicate the error I was having. Would someone with a better understanding of React children and the nature of React hooks know what’s wrong?
[2] I attempted to add onChange attributes to the examples given as a standalone input element and the Avatar element, but it works as planned.