-
Notifications
You must be signed in to change notification settings - Fork 7.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
how to change the state of parent component from child Component if parent state is maintained using useStateHook #1689
Comments
Hi! There's no difference in this scenario between function and class components. In both cases, you want to pass a callback function down to the parent. Let's begin with a class example: class Parent extends React.Component {
state = { value: "" }
handleChange = (newValue) => {
this.props.setState({ value: newValue });
}
render() {
// We pass a callback to MyInput
return <MyInput value={this.state.value} onChange={this.handleChange} />
}
}
class MyInput extends React.Component {
handleChange = (event) => {
// Here, we invoke the callback with the new value
this.props.onChange(event.target.value);
}
render() {
return <input value={this.props.value} onChange={this.handleChange} />
}
} With hooks, we can follow the same pattern and pass a callback function down to MyInput: function Parent() {
const [value, setValue] = React.useState("");
function handleChange(newValue) {
setValue(newValue);
}
// We pass a callback to MyInput
return <MyInput value={value} onChange={handleChange} />;
}
function MyInput(props) {
function handleChange(event) {
// Here, we invoke the callback with the new value
props.onChange(event.target.value);
}
return <input value={props.value} onChange={handleChange} />
} |
Thanks Philip . I had followed the same approach before posting this question . But i had made small typo while using the use state ( used { } instead of [ ]). Because of that it was not working. Type Error one : Correct One: After making the change it started working Thanks |
@philipp-spiess what if in your scenario the developer wanted to avoid unnecessarily re-rendering the child component (because handleChange is created on each render and is a prop of the child)? The only ways to generally solve this problem seems to be by using Or am I missing something? |
@evbo Depends on what the function is doing! Check out If there are lots of dependencies than you are right, a |
Thanks helping to wrap my head around react! I suppose there are a couple other tricks that may be useful in special scenarios where the child must modify state based on some
These cases are outlined nicely here: https://www.codebeast.dev/usestate-vs-useref-re-render-or-not/#what-causes-re-rendering |
Also, side note: I don't always like the coding convention with
|
I'm pretty certain that this is a valid pattern! Especially since it is equivalent to this useMemo version: const memoizedCallback = React.useMemo(() => {
return event => {
doSomething(a, b, event);
};
}, [a, b]); |
Thank you, all of the docs had me confused no arguments should be provided. I guess the author was trying to keep it tl;dr friendly, so this is good to know! |
I tried this solution, but it only works on the first invocation in my child component.
How do I get |
Philip, this is great, but I tried something similar with multiple inputs and it doesn't work. If you could provide an example with multiple inputs that use one handleChange function based on their name, that would be super helpful! Thanks! |
Hi, I have a problem when trying to update the parent state via child component in a functional component.
I have this method in the parent component called from the child component but all the state values I access are the BASE values of each state variables, even if they are correctly changed beforehand. |
How could i test a similar scenario? I have already written functionality to pass useState setter method and value as props to child component. These values are set in the child component. How can i replicate this in a unit test with jest? So far i have
The last line fails, the mock useState func fires yet the state in parent doesnt seem to reflect the change, disabled is still true but should now be false. The getCourseListViewWrapper(); is return a shallow render via enzyme. |
Hi, is there any real difference between doing that and passing down directly the setter as a prop?: return <MyInput value={value} onChange={setValue} />; Thank you! |
How to define types without using any? |
also curious about this, any ideas? |
After thinking about it, I found that the custom handler method can be even worse in certain situations, for example if you have memoized the child component, as in every rerender the handler would be different but the setter will not. This is an advantage of passing the setter instead of a handler function. The advantage of using a handler is maybe legibility? I dont know, if the handler is only going to do a setState I would not create it. |
I'm running into an issue where when the callback is called a second time the state is stale and not updated. Any ideas on how to remedy this? |
I agree with the approach of passing the However, this pattern is similar to directly passing a |
Hi Team,
I have started using the hooks. And come across a scenario where i have to change the state of the parent component from the child component . But I am maintaining the parent component state using useState hook . So i am not getting access to the function to change this state from the child component . Can you provide information on how can I achieve this.
Thanks
Girish hT S
The text was updated successfully, but these errors were encountered: