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

Polyfill for getSnapshotBeforeUpdate #1

Merged
merged 9 commits into from
Mar 28, 2018
Merged

Conversation

bvaughn
Copy link
Contributor

@bvaughn bvaughn commented Mar 22, 2018

Potential polyfill for getSnapshotBeforeUpdate (RFC: reactjs/rfcs/pull/33, implementation: facebook/react/pull/12404).

Note that if we did use this approach, we'd need to update React to also look for a __suppressDeprecationWarning flag on the componentWillUpdate method before logging a DEV warning. (Added to facebook/react/pull/12404)

I'm currently on the fence about whether we should polyfill getSnapshotBeforeUpdate using this technique. It would be useful for libs that rely on it, so they could avoid having to break backwards compatibility with supported React versions.

@bvaughn bvaughn changed the title POC polyfill for getSnapshotBeforeUpdate [do not merge] polyfill for getSnapshotBeforeUpdate Mar 23, 2018
index.js Outdated
var prevState = this.state;
this.props = nextProps;
this.state = nextState;
this.__reactInternalSnapshot = this.getSnapshotBeforeUpdate(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would probably need to be in try/finally if we do this. In case it throws.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rats. I meant to add that and forgot. 😄

If we move forward with this PR (which I doubt) I'll add it.

@bvaughn bvaughn changed the title [do not merge] polyfill for getSnapshotBeforeUpdate [POC] polyfill for getSnapshotBeforeUpdate Mar 23, 2018
@bvaughn
Copy link
Contributor Author

bvaughn commented Mar 23, 2018

I've updated the README to specify which lifecycles are supported, and to link to React docs for more information instead of duplicating.

Even if we don't move forward with this PR, I'll probably keep most of the README changes.

README.md Outdated
Note that in order for the polyfill to work, none of the following lifecycles can be defined by your component: `componentWillMount`, `componentWillReceiveProps`, or `componentWillUpdate`.

Note also that if your component contains `getSnapshotBeforeUpdate`, `componentWillUpdate` must be defined as well.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean componentDidUpdate?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In other words I'd expect the person trying to use getSnapshotBeforeUpdate to want to migrate away from componentWillUpdate, not use it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes 😦 This was a typo.

@bvaughn bvaughn requested review from sebmarkbage and gaearon March 26, 2018 22:22
@bvaughn bvaughn changed the title [POC] polyfill for getSnapshotBeforeUpdate Polyfill for getSnapshotBeforeUpdate Mar 26, 2018
var prevState = this.state;
this.props = nextProps;
this.state = nextState;
this.__reactInternalSnapshot = this.getSnapshotBeforeUpdate(
Copy link

@Jessidhia Jessidhia Mar 28, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the kind of thing for which a WeakMap would be good for... but can't use WeakMap in React :(

Have you tried at least making it non-enumerable, or even maybe also a polyfill-internal Symbol instead of a string name, or are those also out when supporting 0.14?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that's necessary. React already stores other "__reactInternal" attributes on class components. And relying on a symbol might cause problems for older browsers (supported by older versions of React) that don't support symbols.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice if a future version of React would use a WeakMap for their per-instance internal state instead (React 17?) 🤔

var prevProps = this.props;
var prevState = this.state;
this.props = nextProps;
this.state = nextState;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't direct assignments to these warn?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. React sets/updates this values in a similar way before calling lifecycles.

@bvaughn
Copy link
Contributor Author

bvaughn commented Mar 28, 2018

We reached consensus today on moving forward with this polyfill approach- so now I just need a review 😄

index.js Outdated
}
if (typeof Component.prototype.componentDidUpdate !== 'function') {
throw new Error(
'Cannot polyfill getSnapshotBeforeUpdate() for components that do not define componentDidUpdate()'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add "on the prototype" to these messages?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Member

@gaearon gaearon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Would be nice to have a test that more closely mimics the intended usage (e.g. that uses refs).

@bvaughn
Copy link
Contributor Author

bvaughn commented Mar 28, 2018

Fair enough. Updated!

@bvaughn bvaughn merged commit 25a7dd4 into master Mar 28, 2018
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

Successfully merging this pull request may close these issues.

3 participants