Reputation: 65
I have e child component named Window and I have this useState in Window component:
Window Component:
const [showWindow, setShowWindow] = useState(false);
Imagine this is the parent component
Parent component :
/////
////
////
<Window/>
<Button/ onClick={()=>{
setShowWindow(true)
}}>
/////
/////
As it can be seen I have a Button component here and I want to set the showWindow to 'true' through it.
How can I change the useState in the child component from its parent component like this example? How can I access to it?
Upvotes: 4
Views: 3946
Reputation: 37
Another way would be to reload the child component, causing it to reset the useState to its initial state.
import React, { useState } from 'react';
function ParentComponent() {
const [resetKey, setResetKey] = useState(0);
const resetChildComponent = () => {
// Increment a key to reset the child component
setResetKey((prevKey) => prevKey + 1);
};
return (
<div>
<button onClick={resetChildComponent}>Reset Child</button>
<ChildComponent key={resetKey} />
</div>
);
}
function ChildComponent() {
const [childState, setChildState] = useState('Initial State');
return (
<div>
<p>Child State: {childState}</p>
<button onClick={() => setChildState('New State')}>Change State</button>
</div>
);
}
export default ParentComponent;
Upvotes: 0
Reputation: 203542
To invoke functions in a child component use the useImperativeHandle
hook in the Window
component and forward a ref from the parent component to the child to imperatively invoke a function to update the state in the child.
Example:
Window
import { forwardRef, useImperativeHandle, useState } from 'react';
const Window = forwardRef((props, ref) => {
const [showWindow, setShowWindow] = useState(false);
useImperativeHandle(ref, () => ({
showWindow: () => setShowWindow(true),
}));
...
});
Parent
import { useRef } from 'react';
...
const windowRef = useRef();
...
<Window ref={windowRef} />
<Button onClick={() => windowRef.current.showWindow()}>
Show Window
</Button>
Upvotes: 3
Reputation: 155
If I understand the question correctly, you would like to have the parent, able to change state that is defined in the child.
I don't believe this is possible exactly as described. A better solution might be to define the state inside the parent, then pass down the state to the child.
Parent component :
const [showWindow, setShowWindow] = useState(false);
<Window showWindow = {showWindow} setShowWindow = {setShowWindow}/>
<Button/ onClick={()=>{
setShowWindow(true)
}}>
that should produce the functionality I think you are after. Furthermore, you can also pass the setter if you need to change the window within the window component ( which you likely do if this is a popup type component)
As another answer suggested, a further solution would be to use global state/context. This would allow you to avoid passing state around, but has more overhead
Upvotes: 3