Skip to content

Instantly share code, notes, and snippets.

@jimfb
Last active January 22, 2016 22:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jimfb/9ef9b46741efbb949744 to your computer and use it in GitHub Desktop.
Save jimfb/9ef9b46741efbb949744 to your computer and use it in GitHub Desktop.

Suppose a parent renders <ChildComponent callback={(value)=>setState(value)} />. Suppose the parent re-renders. The pointer values of the callback prop will be different (ie. not triple-equals-equal) but the callback prop's value is conceptually the same for all intents and purposes. This is a "new value" despite being the "same value". You run into the same problem when the parent creates an object <ChildComponent data={{foo: 'bar', bar: 'noise'}} /> (pointers differ, despite it being the "same" object from a value-type perspective).

You also run into the reverse problem due to mutability. Suppose I say:

var value = {foo: 'bar', bar: 'noise'};
ReactDOM.render(<ChildComponent data={value} />, ...);
value.bar = 'drinks';
ReactDOM.render(<ChildComponent data={value} />, ...);

As you can see, the props have clearly "changed" (ie. componentWillReceiveProps should get called, so the ChildComponent can respond accordingly), but the values are triple-equals-equal.

In general, there is no way to solve this, except to always call componentWillReceiveProps any time the values might have changed.

If javascript always used value types (like they do for integers; two renders of integers or strings are always "equal" if they are equal from a value-type definition) for all data types, than this problem would not exist. Also, mutation creates an issue, because the meaning of a value can change (when it is mutated) but is still triple-equals equal to the original prop. But because javascript uses reference equality and supports mutation, you can't rely on triple-equals to tell you if two things are conceptually the same.

@kmalakoff
Copy link

@jimfb I believe this gist was most likely started due to a misunderstanding in terms of the spirit of the line of solutions that I was trying to put forward to solve the issue. My point was not strongly rooted in having an update method added (it was just an example around consolidating the prop methods), but more importantly I was trying to move the discussion away from being anchored or overly-focussed on defending the addition of a new method to considering a more broad set of solutions (such as reducing multiple code paths, standardizing the method signatures, replacing the current prop method with another, etc) and to include the feedback from other contributors into the principles that could be used to evaluate solutions.

I took the time to explain to you in this gist why focussing on the value-type and mutability points and focussing on the update method example was a bit of a red herring (choosing the update lifecycle hook was not a significant point in my analysis) and I took this opportunity to put forward how other improvements triggered by the prop API improvements might fit into the bigger picture since it is quite possible that the best solution may in fact lead down the path of a larger change.

I acknowledge that my understanding of all of the issues that went into the React API is not as deep as people closer to it, but on the other hand, I am a very experienced software architect and open source library maintainer who deals with API design tradeoffs on a regular basis and I've been using React as a user for a while now so I have been considering what changes could be made to improve productivity.

It is a bit of a shame that the approach taken by the Facebook team has been to narrow the potential solution space being considered for resolving the issue and to classify related considerations as being out of scope. Unfortunately, it feels like it has been and will be a poor ROI for my time to continue with this discussion under these circumstances so I will also bow out.

At least there is a record of principles that the React team could consider. As you can see from these principles and potential solution that I have tried to promote discussion on, I believe the React API can and should be simplified. I hope you all consider ways to simplify the API and to make it even better for all!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment