Reputation: 759
Seen similar issues here, but couldn't wrap my mind on how this works. New to functional components and React overall.
Parent
contains the Child
, which is a modal. Parent has a div
that triggers showing the Child
modal, and the Child
modal has a close
button that triggers its hiding. When I click on the div
component in Parent
, I need to show and hide the Child
modal. When I click on the close
button in the Child
, I need to hide the Child
component.
The Parent component:
import React, { useState } from "react";
import Child from "./Child";
const Parent = () => {
const [buttonState, setbuttonState] = useState({
buttonState: false,
});
const onParentClick = (e) => {
e.preventDefault();
setbuttonState(!buttonState);
};
return (
<div>
<div onClick={onParentClick}></div>
<Child isOpen={buttonState} onParentClick={onParentClick} />
</div>
);
};
export default Parent;
The Child component:
import React, { useState } from "react";
const Child = (props) => {
const [buttonState, setButtonState] = useState({
buttonState: props.isOpen,
});
const onChildClick = (e) => {
e.preventDefault();
setButtonState(false);
props.onParentClick();
};
return (
<div
className={
buttonState ? "child-modal-opened" : "child-modal-closed"
}
>
<div onClick={onChildClick}>Close</div>
</div>
);
};
export default Child;
For some reason, can't make this work. What am I missing here?
Upvotes: 0
Views: 1362
Reputation: 2131
Looks like useState()
is used incorrectly.
const [buttonState, setbuttonState] = useState({
buttonState: false,
});
results in buttonState
being { buttonState: false}
, so setbuttonState(!buttonState)
does not work as intended.
Here's updated Parent component with useState(false)
instead (setting initial buttonState
value to false
)
import React, { useState } from "react";
import Child from "./Child";
const Parent = () => {
const [buttonState, setbuttonState] = useState(false);
const onParentClick = (e) => {
e.preventDefault();
setbuttonState(!buttonState);
};
return (
<div>
<div onClick={onParentClick}></div>
<Child isOpen={buttonState} onParentClick={onParentClick} />
</div>
);
};
export default Parent;
P.S.
As @Will suggested, there is no need to create another state in Child, it can be passed from Parent
import React, { useState } from "react";
const Child = (props) => {
return (
<div
className={
props.isOpen ? "child-modal-opened" : "child-modal-closed"
}
>
<div onClick={props.onParentClick}>Close</div>
</div>
);
};
Upvotes: 3
Reputation: 59
It looks like onParentClick is defined so as to take an event object as a parameter and call preventDefault() on that, but you're calling it without any arguments. Does it work like this: props.onParentClick(e);
?
Upvotes: 0