Skip to content

Commit 4610392

Browse files
committed
Changes in response to Sophie's feedback
1 parent 712f4de commit 4610392

File tree

4 files changed

+18
-20
lines changed

4 files changed

+18
-20
lines changed

content/blog/2018-03-27-update-on-async-rendering.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ One of the biggest lessons we've learned is that some of our legacy component li
1111
* `componentWillReceiveProps`
1212
* `componentWillUpdate`
1313

14-
These lifecycle methods have often been misunderstood and subtly misused; furthermore, we anticipate that their potential misuse may be more problematic with async rendering. Because of this, we will be adding an "UNSAFE_" prefix to these lifecycles in an upcoming release.
14+
These lifecycle methods have often been misunderstood and subtly misused; furthermore, we anticipate that their potential misuse may be more problematic with async rendering. Because of this, we will be adding an "UNSAFE_" prefix to these lifecycles in an upcoming release. (Here, "unsafe" refers not to security but instead conveys that code using these lifecycles will be more likely to have bugs in future versions of React, especially once async rendering is enabled.)
1515

1616
## Gradual Migration Path
1717

1818
[React follows semantic versioning](/blog/2016/02/19/new-versioning-scheme.html), so this change will be gradual. Our current plan is:
1919

2020
* **16.3**: Introduce aliases for the unsafe lifecycles, `UNSAFE_componentWillMount`, `UNSAFE_componentWillReceiveProps`, and `UNSAFE_componentWillUpdate`. (Both the old lifecycle names and the new aliases will work in this release.)
21-
* **16.x**: Enable deprecation warning for `componentWillMount`, `componentWillReceiveProps`, and `componentWillUpdate`. (Both the old lifecycle names and the new aliases will work in this release, but the old names will log a DEV-mode warning.)
21+
* **A future 16.x release**: Enable deprecation warning for `componentWillMount`, `componentWillReceiveProps`, and `componentWillUpdate`. (Both the old lifecycle names and the new aliases will work in this release, but the old names will log a DEV-mode warning.)
2222
* **17.0**: Remove `componentWillMount`, `componentWillReceiveProps`, and `componentWillUpdate` . (Only the new "UNSAFE_" lifecycle names will work from this point forward.)
2323

2424
**Note that if you're a React application developer, you don't have to do anything about the legacy methods yet. The primary purpose of the upcoming version 16.3 release is to enable open source project maintainers to update their libraries in advance of any deprecation warnings. Those warnings will not be enabled until a future 16.x release.**
@@ -45,16 +45,12 @@ Together with `componentDidUpdate`, this new lifecycle should cover all use case
4545

4646
### New lifecycle: `getSnapshotBeforeUpdate`
4747

48-
The new `getSnapshotBeforeUpdate` lifecycle is called right before mutations are made (e.g. before the DOM is updated). The return value for this lifecycle will be passed as the third parameter to `componentDidUpdate`.
48+
The new `getSnapshotBeforeUpdate` lifecycle is called right before mutations are made (e.g. before the DOM is updated). The return value for this lifecycle will be passed as the third parameter to `componentDidUpdate`. (This lifecycle isn't often needed, but can be useful in cases like manually preserving scroll position during rerenders.)
4949

5050
Together with `componentDidUpdate`, this new lifecycle should cover all use cases for the legacy `componentWillUpdate`.
5151

5252
We'll look at examples of how both of these lifecycles can be used below.
5353

54-
> Note
55-
>
56-
> For brevity, the examples below are written using the experimental class properties transform, but the same migration strategies apply without it.
57-
5854
## Examples
5955
- [Initializing state](#initializing-state)
6056
- [Fetching external data](#fetching-external-data)
@@ -64,6 +60,10 @@ We'll look at examples of how both of these lifecycles can be used below.
6460
- [Updating external data when props change](#updating-external-data-when-props-change)
6561
- [Reading DOM properties before an update](#reading-dom-properties-before-an-update)
6662

63+
> Note
64+
>
65+
> For brevity, the examples below are written using the experimental class properties transform, but the same migration strategies apply without it.
66+
6767
### Initializing state
6868

6969
This example shows a component with `setState` calls inside of `componentWillMount`:
@@ -102,7 +102,7 @@ People often assume that `componentWillMount` and `componentWillUnmount` are alw
102102
For this reason, the recommended way to add listeners/subscriptions is to use the `componentDidMount` lifecycle:
103103
`embed:update-on-async-rendering/adding-event-listeners-after.js`
104104

105-
Sometimes it is important to update subscriptions in response to property changes. If you're using a library like Redux or MobX, the library's container component should handle this for you. For application authors, we've created a small library, [`create-subscription`](https://github.com/facebook/react/tree/master/packages/create-subscription), to help with this.
105+
Sometimes it is important to update subscriptions in response to property changes. If you're using a library like Redux or MobX, the library's container component should handle this for you. For application authors, we've created a small library, [`create-subscription`](https://github.com/facebook/react/tree/master/packages/create-subscription), to help with this. We'll publish it along with React 16.3.
106106

107107
Rather than passing a subscribable `dataSource` prop as we did in the example above, we could use `create-subscription` to pass in the subscribed value:
108108

@@ -171,7 +171,7 @@ Open source maintainers might be wondering what these changes mean for shared co
171171

172172
Fortunately, you do not!
173173

174-
In support of version 16.3, we've also created a new NPM package, [`react-lifecycles-compat`](https://github.com/reactjs/react-lifecycles-compat). This package polyfills components so that the new `getDerivedStateFromProps` lifecycle will also work with older versions of React (0.14.9+).
174+
When React 16.3 is published, we'll also publish a new npm package, [`react-lifecycles-compat`](https://github.com/reactjs/react-lifecycles-compat). This package polyfills components so that the new `getDerivedStateFromProps` lifecycle will also work with older versions of React (0.14.9+).
175175

176176
To use this polyfill, first add it as a dependency to your library:
177177

examples/update-on-async-rendering/adding-event-listeners-create-subscription.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import {createSubscription} from 'create-subscription';
33
const Subscription = createSubscription({
44
getCurrentValue(sourceProp) {
55
// Return the current value of the subscription (sourceProp).
6-
// highlight-next-line
76
return sourceProp.value;
87
},
98

@@ -14,11 +13,9 @@ const Subscription = createSubscription({
1413

1514
// Subscribe (e.g. add an event listener) to the subscription (sourceProp).
1615
// Call callback(newValue) whenever a subscription changes.
17-
// highlight-next-line
1816
sourceProp.subscribe(handleSubscriptionChange);
1917

2018
// Return an unsubscribe method.
21-
// highlight-range{1-3}
2219
return function unsubscribe() {
2320
sourceProp.unsubscribe(handleSubscriptionChange);
2421
};
@@ -27,7 +24,6 @@ const Subscription = createSubscription({
2724

2825
// Rather than passing the subscribable source to our ExampleComponent,
2926
// We could just pass the subscribed value directly:
30-
// highlight-range{1-3}
3127
<Subscription source={dataSource}>
3228
{value => <ExampleComponent subscribedValue={value} />}
3329
</Subscription>;

examples/update-on-async-rendering/react-dom-properties-before-update-after.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class ScrollingList extends React.Component {
1515
componentDidUpdate(prevProps, prevState, snapshot) {
1616
// If we have a snapshot value, we've just added new items.
1717
// Adjust scroll so these new items don't push the old ones out of view.
18+
// (snapshot here is the value returned from getSnapshotBeforeUpdate)
1819
if (snapshot !== null) {
1920
this.listRef.scrollTop +=
2021
this.listRef.scrollHeight - snapshot;

examples/update-on-async-rendering/react-dom-properties-before-update-before.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
class ScrollingList extends React.Component {
22
listRef = null;
3-
prevScrollHeight = null;
3+
previousScrollHeight = null;
44

55
// highlight-range{1-7}
66
componentWillUpdate(nextProps, nextState) {
77
// Are we adding new items to the list?
88
// Capture the current height of the list so we can adjust scroll later.
99
if (this.props.list.length < nextProps.list.length) {
10-
this.prevScrollHeight = this.listRef.scrollHeight;
10+
this.previousScrollHeight = this.listRef.scrollHeight;
1111
}
1212
}
1313

14-
// highlight-range{1-9}
14+
// highlight-range{1-10}
1515
componentDidUpdate(prevProps, prevState) {
16-
// If prevScrollHeight is set, we've just added new items.
16+
// If previousScrollHeight is set, we've just added new items.
1717
// Adjust scroll so these new items don't push the old ones out of view.
18-
if (this.prevScrollHeight !== null) {
18+
if (this.previousScrollHeight !== null) {
1919
this.listRef.scrollTop +=
20-
this.listRef.scrollHeight - this.prevScrollHeight;
21-
this.prevScrollHeight = null;
20+
this.listRef.scrollHeight -
21+
this.previousScrollHeight;
22+
this.previousScrollHeight = null;
2223
}
2324
}
2425

0 commit comments

Comments
 (0)