I've asked this problem yesterday and got an answer that I understood and tried to implement. I'm having problems accessing the state variable in my modal after I call it in the parent component.
Here is the state variable I've setup:
const [show, setShow] = useState(false);
Here is how I call that modal in my parent component and here is my modal component and how I use that closeModal
function in my modal props:
export const Modal = (props) => {
const test = props.person.name;
const fname = props.person.fname;
const patientid = props.person.patientid;
//this function should be in the props array, but its not there.
const setshow = props.closeModal;
const url = "https://testcf-boisterous-ardvark-pc.mybluemix.net/test/addAppointment?pid=999998&date=${state.date}&starttime=${state.stime}:00&timecost=00:09:00&name=${state.fname},${state.lname}&reason=${state.type}";
useEffect(async () => {
try {
const response = await axios(url);
const data = response.data;
console.log("testing our useeffect");
console.log(data);
}
catch(error) {
console.log(error.response);
}
}, []);
if (!props.show) {
return null
}
const fetchData = async () => {
//console.log("calling fetchData");
try {
const response = await axios(url);
const data = response.data;
console.log(data);
}
catch(error) {
console.log(error.response);
}
}
return (
<div className="modal" onClick={props.onClose}>
<div className="background" onClick={e =>e.stopPropagation()}>
<div>
<h4 className="margin-bottom">Saving to Master</h4>
<h4 className="margin-top">Confirming Your Booking</h4>
<img src={logo} alt="logo image" />
<h2 >Save and Submit Timeslot</h2>
<h4>for <span >{test}</span></h4>
<div>
<h5>{patientid}</h5>
<img src={boxes} alt="Two Double Boxes" />
</div>
</div>
<div className="modal-footer">
<button className="btn-close" onClick={props.onClose}>Cancel</button>
<button className="btn-submit" onClick={props.onClose}>Confirm</button>
</div>
</div>
</div>\
)
};
export default Modal;
I use the modal like this:\
<Modal
closeModal={setshow}
person={{
name: state.fname,
imageId: '1bX5QH6',
notificationTitle: 'Regular Appointment',
time: state.stime,
adate: state.date,
timecost: state.timecost,
reason: state.type,
patientid: '999999'
}}
/>
CodePudding user response:
You're setting state wrong, like Amin pointed out in their answer.
You want to pass a function to your Modal
component that the Modal
will later invoke when it wants to close, effectively bubbling the state to the parent component. You'll also pass the current value of show
to the Modal, so it knows if it should display or not.
This is how you'll pass it to your Modal
:
<Modal
closeModal={() => setshow(false)}
show={show}
...
/>
Then, within your modal, do not have const setshow = props.closeModal
, you don't need that.
Within your modal component, you can return early if !props.show
, just like you're doing:
// effectively depends on the parent's state, since it's passed down
if (!props.show) {
return null
}
And then, to solve your issue, simply:
onClick={props.closeModal}
// which is equivalent to
onClick={() => props.onClose()}
So it will call the function that was passed to it, which (in this case) will update the state in the parent. This is the pattern all Modal libraries I've used tend to use. It's powerful because you can pass it more complicated functions into closeModal
when calling your modal, allowing you to easily take other actions when a modal is closed besides just updating your show state.
That will work now, since props.closeModal
CodePudding user response:
"const setshow = props.closeModal" That's not the right way to update a state.
Try setShow(props.closeModal).