Skip to content
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

v16.4.2 - getDerivedStateFromProps is called after calling setState #13480

Closed
TacB0sS opened this issue Aug 25, 2018 · 16 comments
Closed

v16.4.2 - getDerivedStateFromProps is called after calling setState #13480

TacB0sS opened this issue Aug 25, 2018 · 16 comments

Comments

@TacB0sS
Copy link

TacB0sS commented Aug 25, 2018

I've being using version 16.2 till 2 hours ago, and when things were not what I expected I read this which made MUCH more sense than what I was doing so far... so I upgraded to 16.4.2, and things stopped working, mainly cause getDerivedStateFromProps is called after calling setState.

is this a desired behaviour? I doubt it cause the props hasn't changed, and the entire goal of the method is to unify props pre-processing logic for new and updated component and unify the way developers apply the props to the state.

i've checked 16.3.0, and 16.3.2, in these version setState does not trigger getDerivedStateFromProps.

@TrySound
Copy link
Contributor

#13015
#12898

@TacB0sS
Copy link
Author

TacB0sS commented Aug 25, 2018

@gaearon

ok... so this seems like a works as designed... please rename this misleading method name :)
getDerivedStateFromProps implies that I need to derive the state from the props...

@TacB0sS TacB0sS closed this as completed Aug 25, 2018
@TrySound
Copy link
Contributor

Do you want to write getDerivedStateFromPropsAndPrevState?

@TacB0sS
Copy link
Author

TacB0sS commented Aug 25, 2018

or just deriveState...

@gaearon
Copy link
Collaborator

gaearon commented Aug 25, 2018

The purpose of the method is still to derive state from props. We call it more often to prevent common bugs, but it doesn’t mean the purpose of the method changed.

In any case it’s likely you’re using this method without a good reason. Please see the blog post where we describe simpler alternatives: https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html

@TacB0sS
Copy link
Author

TacB0sS commented Aug 25, 2018

Yeah.. I kind of do need it.. as my component remains on screen a new instance is not created but its props does cause it renders a new object. and the only way to do it is by getting the props and do some preprocessing on the props.

I think the issue is the fact that in order to use this method correctly you force/assume that developer would have an id to be able to understand if there was a change or not.. so they need to preserve a prop in the state in order to know if I got new props..

so let me ask you this:

What is the point in making this method static, when it is actually stateful(you pass the prevstate)?
if the method is static how do you manage Component Classes hierarchy that implement this method(I didn't get there yet.. but I can see this coming)?

@jquense
Copy link
Contributor

jquense commented Aug 25, 2018

please read all the existing conversation around this method, including the blog post linked above, before asking folks to re-say everything that has been said already thanks!

@TacB0sS
Copy link
Author

TacB0sS commented Aug 25, 2018

I did... I really do appreciate you guys responsiveness... but I still disagree :)

@gaearon
Copy link
Collaborator

gaearon commented Aug 25, 2018

as my component remains on screen a new instance is not created but its props does cause it renders a new object. and the only way to do it is by getting the props and do some preprocessing on the props.

Not the only way.

You can also force it being re-created by providing a key that changes when you need to reset the state. This is described here.

Your "preprocessing on the props" is also vague. If you just want to calculate some data based on props, you don't need state for this at all. Instead, calculate it right where you'd use it (e.g. in the render method). Or memoize it if necessary. This is described here.

What is the point in making this method static, when it is actually stateful(you pass the prevstate)?

It is to discourage people from putting side effects or mutating instance fields there (which would defeat the purpose of introducing a new method).

how do you manage Component Classes hierarchy that implement this method

Don't use inheritance hierarchies in React. If you insist, you can do it of course, but then it's up to you to figure out how you'll manage it.

@TacB0sS
Copy link
Author

TacB0sS commented Aug 25, 2018

@gaearon dude.. you are extremely patient and I do appreciate your posts and your detailed replies I read a lot of them.

You can also force it being re-created by providing a key that changes when you need to reset the state. This is described here.

I understand, I have components of both controlled and uncontrolled types. I have everything from a custom checkbox to an object properties editor by object type(can be a complex object with tens of fields, so there can be also sub-editors).

Your "preprocessing on the props" is also vague

when I get an object to the editor it might be missing some properties(old version, bug,..) in the preprocessing I initialize objects, arrays, or other editable properties and assign default values to them.. that is the purpose of a editor, to edit and create that object type.

It is to discourage people from putting side effects or mutating instance fields there (which would defeat the purpose of introducing a new method).

That is what I thought :)

Don't use inheritance hierarchies in React. If you insist, you can do it of course, but then it's up to you to figure out how you'll manage it.

Luckily I had my fair share of Hierarchy vs. Composition as a Java developer (12 years now :)) so yes in some places I do need the abstraction to force commonality for the inheriting objects. (the editors for example).

From another post:

So why is that a problem? If any of the parents re-render, getDerivedStateFromProps would also get called again on your component. In your example, even with React 16.3, a parent re-render would reset the selection values though the document ID hasn’t changed. Your analytics call would also fire twice.

then I have no choice but to pass a prop which would act as a unique id... in case of a controlled component, and distinct that a new object is about to render...

Thanks.

@gaearon
Copy link
Collaborator

gaearon commented Aug 25, 2018

dude.. you are extremely patient and I do appreciate your posts and your detailed replies I read a lot of them.

Haha thanks, glad to help.

when I get an object to the editor it might be missing some properties(old version, bug,..) in the preprocessing I initialize objects, arrays, or other editable properties and assign default values to them.. that is the purpose of a editor, to edit and create that object type.

You might want to check this out because it sounds relevant: #12898 (comment). In particular I'd solve this by applying default values at the point where you need them, instead of trying to propagate them upwards.

@gaearon
Copy link
Collaborator

gaearon commented Aug 25, 2018

Maybe if you provide a reduced runnable example of what you're trying to accomplish, I could look at refactoring it too.

@TacB0sS
Copy link
Author

TacB0sS commented Aug 25, 2018

Haha thanks, glad to help.

🥇

You might want to check this out because it sounds relevant: #12898 (comment). In particular I'd solve this by applying default values at the point where you need them, instead of trying to propagate them upwards.

there is a point there I could definitely even move some of these into the rendering method as they will only create one instance and in the future will use the same instance!!!

But some properties are used by children editor.. so they are must be managed by the parent.

thanks a ton..

@TacB0sS
Copy link
Author

TacB0sS commented Aug 25, 2018

Maybe if you provide a reduced runnable example of what you're trying to accomplish, I could look at refactoring it too.

its not that I don't understand.. it is more difficult to accept this concept because it breaks the barrier between new props and a new state, you know what I mean...

@gaearon
Copy link
Collaborator

gaearon commented Aug 25, 2018

If you provide an example I can still try to look at it. :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants
@jquense @gaearon @TacB0sS @TrySound and others