I want to invoke a function from one component to another component to open a element, it’s working fine but fires only once, can anyone please help me to get this working.
Component One should open whenever clicked on openmodal button even for n number of times.
function App() {
let [modal, setModal]= useState(false)
return (
<div className="App">
<div>
<One modal={modal}/>
<Two onModal={setModal}/>
</div>
</div>
)
}
export function One({modal}) {
let [open, setOpen] = useState(false)
useEffect(() => {
setOpen(modal)
}, [modal])
const openModal = () => {
setOpen(true)
}
const closeModal = () => {
setOpen(false)
}
return (
<>
<div>
<button onClick={openModal}>Create</button>
{open && <div>MODAL WINDOW<br /><br /><br /><span onClick={closeModal}>CLOSE</span></div>}
</div>
</>
)
}
export function Two({onModal}) {
return (
<>
<div>
<button onClick={() => onModal(true)}>Open Modal</button>
</div>
</>
)
}
I appreciate your response on this query
2
Answers
There are 2 flags that determines whether component
<One />
will show up or not —open
in<One />
modal
in<App />
When you open the model, both
open
andmodal
are set totrue
(due tosetState
andsetState
inuseEffect
).However, once you "CLOSE" it with the
onClick
event in<One />
, despiteopen
is set tofalse
, themodal
is stilltrue
.Why does that matter you might ask? Remember the dependency you have added in the
useEffect
block, the code inside it only updates when React detects a dependency has been updated. In this case, sincemodal
remainstrue
after we clicked "CLOSE", thesetState
inside it will never be trigger. Worse, even if it does, themodal
will still go fromtrue
totrue
.The fix to it is to either pass the
setModal
component<One />
and addsetModal(false)
in thecloseModal
method. Or bubble the control ofonClose
to the<App />
.Example —
Let us trace the flow:
As a result, the component One reappears.
A fix may be this:
Add inverse data flow from the component One as well.
This will keep the two states – open and modal in sync.
Please see below the modified code and the results.
App.js
Test results: