-
Notifications
You must be signed in to change notification settings - Fork 217
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
Props change does not re render #17
Comments
@jeff-lau a new set of props coming in for a component will always cause it to try to re-render (I say try because you can stop rendering with
|
@NiGhTTraX thank you for replying! I find that, if a parent container changes the props passed in to a child component. The child component does not re-render automatically. The way I can get it to re-render is to update the state of the child component with the new props in the componentWillReceiveProps method. That seems to be the way how react behaves? |
In your example you're mutating the You should never manually update Container {
state= { foo: 123 }
handleEvent() {
this.setState({ foo: 456 })
},
render() {
return <Child foo={this.state.foo} />
}
Child {
render() {
return <div>{this.props.foo}</div>
}
} |
Thanks @NiGhTTraX for the clarification. I am just starting with React and I wasn't sure that updating the props from outside will cause re-render (because this is what I need). I came across the stackoverflow example and I thought it is indeed not okay to change props inside a component. Your clarification clears things up. Bottom line is I am passing props from parent to child without of course mutating them ever. So if the prop does change (from an even external component, like GrandParent) then react will re-render. The only situation I have found to actually look for prop change is, if I am using one of the props to set an initial state. Then I would not set any state at Further down I may use So please correct me if my understanding is wrong. Thank you. |
@swashata your understanding is correct. I just want to clarify one small thing for future readers:
At least with the current API in 16.3.0, state needs to be defined in the constructor before calling
|
@NiGhTTraX Thanks for the pointer. I was already setting Bdw, could you please do a quick review of the codebase I am working on? I will be very glad 😅 |
Great pointer about the forceUpdate when new props are passed to the component in some edge case scenarios. I may try the getDerviedStateFromProps in the future. I agree with your comment @swashata that "The only situation I have found to actually look for prop change is, if I am using one of the props to set an initial state", plus of course setting static items. I ran into a conundrum earlier today where I wanted to get the derived state from the initial props, so I did this https://stackoverflow.com/questions/50103629/passing-data-from-ajax-call-to-view-in-react-native. Seems to work for me, thought I'd pass the knowledge along. Thanks for clearing some things up for me @NiGhTTraX; reading this conversation helped validate my solution. |
@NiGhTTraX I have a small question: I have Is is somewhat expected? |
Hey @bologer, can you provide some example code? |
Guys, I am having a problem with re-rendering of a component (and came here Googling) on its props change: Component rendered in parent:
Change state in parent:
onClick method in child:
Set state fires for sure, as another component, that takes its props from state re-renders immediately:
I hope I am not hijacking the thread. EDIT: RESOLVED! I found my (probably newbie mistake). It was very simple: I was assuming that the constructor of the child would be called whenever props is changed and was copying props to state, then using state in the render functions. Apparently, constructor of child did not run when props were changed. Once I started using props instead of state in child function everything started working. |
Thank you, @finkbg. I had made the exact same wrong assumption about the |
I think should be use Vuex, put the model object for react with parent and children components. in vue template(ui), you can bind the object (from $store.state.object). when the object changed by this.$store.commit('updateObject', newObject); your children component will be render. The means: parent, children component, even sibling components share same model object with Vuex |
Excellent! Child should not keep this as state if it is property replication. If it is transforming then event passing and transform again. |
I didn't test it with
I am using both the props and the state of
|
@Guneetgstar The combination of
But here is the thing, in your example, you do not need to create a state at all. If what you want is the value of the expression export function MyComponent(props) {
const { addresses } = props;
return (
<div>Address is {addresses ? addresses[0] : 'Unknown'}</div>
);
} This is a very common mistake to think that we need to sync the state with the prop to show in the UI, I did similar mistakes earlier. I would really recommend you to read this article by @kentcdodds |
@swashata I acknowledge your suggestion but there was a need to store +1 for 3rd point. |
@Guneetgstar I see. Your use case may vary, but it is also possible to do something like const { addresses, dispatch } = props;
const currentAddress = addresses ? addresses[0] : '';
return (
<input type="text" value={currentAddress} onChange={e => {
const newAddresses = addresses ? [...addresses] : [];
newAddresses[0] = e.target.value;
// call redux dispatch to update address
dispatch({
type: 'UPDATE_ADDRESS',
payload: newAddresses,
});
}} />
); But of course it would update your redux store on every keystroke. If you are mapping only needed props to your components, then it wouldn't matter much. Although if performance does become an issue then you can copy the prop to state, keep then in sync and then debounce any update to the local state through your redux dispatcher. |
Hello. Above in thred we have a lot clarification about why props does not trigger re-render. But the React docs tells that they should do. Why?
|
As far as I know changing props doesn't cause a component to re render. Props change will trigger componentWillReceiveProps and will only cause a re render if we update the state in this life cycle method?
The text was updated successfully, but these errors were encountered: