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

getDerivedStateFrom{Props,Catch} should update updateQueue.baseState #12528

Merged
merged 1 commit into from
Apr 3, 2018

Conversation

acdlite
Copy link
Collaborator

@acdlite acdlite commented Apr 3, 2018

Based on a bug found in UFI2.

There have been several bugs related to the update queue (and specifically baseState) recently, so I'm going to follow-up with some refactoring to clean it up. This is a quick fix so we can ship a patch release.

@gaearon
Copy link
Collaborator

gaearon commented Apr 3, 2018

This is hard to follow for me. What is your mental model for when it's safe and/or necessary to mutate baseState? How does this relate to processUpdateQueue that also mutates it?

@gaearon
Copy link
Collaborator

gaearon commented Apr 3, 2018

In particular I'm worried that a low-pri update can mutate baseState and then get interrupted. What guarantees we'll "disregard" that state-from-props next time we process a high pri update?

Copy link
Contributor

@bvaughn bvaughn left a comment

Choose a reason for hiding this comment

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

I think the fix makes sense. (Also agree with the suggestion to refactor.)

@acdlite
Copy link
Collaborator Author

acdlite commented Apr 3, 2018

We mutate baseState whenever we process the update queue. It represents the state before any of the updates in the queue are applied. It's different from memoizedState whenever we process an update but keep it in the queue. This happens when there are lower priority updates than what we're currently rendering, because we skip the low ones and come back to them later — i.e. it's what makes this work:

react explainer slides 004

My mental model for getDerivedStateFromProps is a setState inside render, at the same priority as what we're currently rendering:

render() {
  if (this.props !== previousProps) {
    this.setState(getDerivedStateFromProps(this.props, this.state));
  }
  // ...
}

If we actually implemented it this way, then processUpdateQueue would have taken care of updating baseState and this bug probably wouldn't have happened. We decided not to use the updateQueue to implement getDerivedStateFromProps because we wanted to avoid adding updates to the current queue, which shares a persistent structure. I thought it would be more elegant. But this bug indicates that it's more complicated than we thought, and we should reconsider. This is one of the things I will address in my follow-up PR.

@bvaughn
Copy link
Contributor

bvaughn commented Apr 3, 2018

If we actually implemented it this way, then processUpdateQueue would have taken care of updating baseState and this bug probably wouldn't have happened.

But the nextState prop passed to componentWillUpdate would have been incorrect.

Based on a bug found in UFI2.

There have been several bugs related to the update queue (and
specifically baseState) recently, so I'm going to follow-up with some
refactoring to clean it up. This is a quick fix so we can ship a
patch release.
@acdlite acdlite merged commit 0f2f90b into facebook:master Apr 3, 2018
@acdlite
Copy link
Collaborator Author

acdlite commented Apr 3, 2018

@bvaughn What's a componentWillUpdate?

@maulberto3
Copy link

maulberto3 commented Apr 10, 2018

Hi @acdlite I just wanted to point out that my getDerivedStateFromProps() stopped working in my React 16.3.0., but as soon as I updated it to 16.3.1., it started working again.
Thanks.

However, my this.forceUpdate() -inside getDerivedStateFromProps()- stopped working. Maybe it's related? I am getting the TypeError: Cannot read property 'forceUpdate' of null error.

Edit: It's not working anywhere inside getDerivedStateFromProps(), but it is working inside custom methods of a React component. Does this help?

@gaearon
Copy link
Collaborator

gaearon commented Apr 10, 2018

this.forceUpdate (an instance method) is not supposed to work inside getDerivedStateFromProps (a static method). Why are you trying to use it? getDerivedStateFromProps() should be pure and have no side effects.

@gaearon gaearon deleted the basestate-bug branch April 10, 2018 17:09
@maulberto3
Copy link

maulberto3 commented Apr 10, 2018

@gaearon Before, I just had some logic that used forceUpdate() inside componentWillReceiveProps(). Particularly, I used it in a Google Maps React component. As the map receives dropdown values, the map showed particular markers (http://crc-sen-maps.herokuapp.com/). Now the forceUpdate() part came when clicking on those markers, in order to show/hide InfoWindows for those particular markers.

Anyhow, since React is preparing ground for async, will refactor it as per your comment.

Thanks again.

P.S. I am using Michele Bertoli's React Google Maps React repo (https://github.com/MicheleBertoli/react-gmaps)

@gaearon
Copy link
Collaborator

gaearon commented Apr 10, 2018

forceUpdate() inside componentWillReceiveProps() doesn't seem very useful because the component is already updating. Hard to say more without seeing the code.

@maulberto3
Copy link

maulberto3 commented Apr 10, 2018

forceUpdate() inside componentWillReceiveProps() doesn't seem very useful because the component is already updating. Hard to say more without seeing the code.

I agree, very hard coded.
This is what I had inside componentWillReceiveProps() for showing/hiding InfoWindows for current on-screen markers, you can see the forceUpdate() thrown in there, for both onClick prop (markers) and onCloseClick prop (infowindows).

if (newProps.dropFiscValue !== this.props.dropFiscValue) {
      const obj1 = {}; //=> Markers, InfoWindows upon Dropdown Fiscalizacion Value
      obj1.markersFisc = {};
      obj1.iWsFisc = {};
      obj1.iWVisibleFisc = {};

      fisc_data.map((marker, index) => {
        // mapping over Área Inversiones data

        if (newProps.dropFiscValue === marker.empresa_responsable2) {
          const index2 = 'marker' + index.toString(); // id for Markers
          const markerFisc = {};

          const index3 = 'marker' + index.toString() + 'IW'; // id for infoWindows
          const iWFisc = {};

          const index4 = 'marker' + index.toString() + 'IW' + 'IsVisible'; // id for infoWindows State
          const iWState = {};
          iWState[index4] = false;

          iWFisc[index3] = (
            <InfoWindow
              key={marker.consec * -1}
              lat={marker.latitud}
              lng={marker.longitud}
              content={
                '<h2>' +
                marker.nombre_del_proyecto +
                '</h2> <hr/>' +
                '<b><b>' +
                marker.empresa_responsable +
                '</b></b><br/>' +
                '<b>Fase: </b>' +
                marker.fase +
                '<br />' +
                '<b>Dimensión (MW): </b>' +
                marker.dimesion +
                '<br />' +
                '<b>Inicio Planificación: </b>' +
                marker.fecha_inicio_planemiento +
                ' <br />' +
                '<b>Fin Factibilidad y Evaluación: </b>' +
                marker.fecha_fin_fact_eval +
                ' <br />' +
                '<b>Gasto Preinversión (millones de colones): </b>' +
                marker.gasto_preinv_millones_col +
                ' <br />' +
                '<b>Inspección ARESEP: </b><a target="_blank" rel="noopener noreferrer" href="https://www.aresep.go.cr">I-Cuatr 2018 (Ver Informe).</a> <br /> <br />' +
                '<u><b>Descripción</b></u>: ' +
                marker.justificacion +
                '<br /><br />'
              }
              onCloseClick={evt => {
                if (!iWState[index4]) {
                  iWState[index4] = true;
                  obj1.iWVisibleFisc[index4] = iWState[index4];
                  obj1.iWsFisc[index3] = iWFisc[index3];
                  this.forceUpdate();
                } else {
                  iWState[index4] = false;
                  obj1.iWVisibleFisc[index4] = iWState[index4];
                  obj1.iWsFisc[index3] = false;
                  this.forceUpdate();
                }
              }}
            />
          );

          markerFisc[index2] = (
            <Marker
              key={marker.consec}
              lat={marker.latitud}
              lng={marker.longitud}
              icon={'https://cdn.filestackcontent.com/MBJZhRRpeFe3YuCMbciA'}
              title={marker.nombre_del_proyecto}
              opacity={0.9}
              onClick={evt => {
                if (!iWState[index4]) {
                  iWState[index4] = true;
                  obj1.iWVisibleFisc[index4] = iWState[index4];
                  obj1.iWsFisc[index3] = iWFisc[index3];
                  this.forceUpdate();
                } else {
                  iWState[index4] = false;
                  obj1.iWVisibleFisc[index4] = iWState[index4];
                  obj1.iWsFisc[index3] = false;
                  this.forceUpdate();
                }
              }}
            />
          );
          Object.assign(obj1.markersFisc, markerFisc); // obj1.markersFisc[index2] = markerFisc[index2]; // put markers under its own root
          obj1.iWsFisc[index3] = iWState[index4]; // small trick, under IW put all false, then on clicks, update them accordingly
          obj1.iWVisibleFisc[index4] = iWState[index4]; // IW state
        }
      });

      this.setState(prevState => {
        return { obj1 };
      }); // state set: newly created obj
      console.log('----------');
    }

@gaearon
Copy link
Collaborator

gaearon commented Apr 10, 2018

Wow, this is really complex. Why isn't this logic in the render function?

@maulberto3
Copy link

maulberto3 commented Apr 10, 2018

Yes, it is complex, so sorry, my bad.
The reason for this complexity is because the React Google Map wrapper is coded in a way to accept React components as children and render them, i.e.:

<Gmaps lat={...} lng={...} ...props> {/* this is the Google Map mounted */}
  <Marker lat={...} lng={...} ...props> {/* this mounts a marker for a location */}
  <Marker lat={...} lng={...} ...props> {/* this mounts another marker for another location */}
  <Marker lat={...} lng={...} ...props> {/* and so on, and so forth */}_
</Gmaps>

According to the Dropdown values, the markers will be mounted/unmounted to the map (via react children components).

And, inside each rendered marker, I have set an onClick prop for showing/hiding those rendered markers' infowindows individually (hence, the forceUpdate()).

I guesss I should take this last logic out of the onClick props and render them in a different way, although still attached to each rendered markers, mmm...

@gaearon
Copy link
Collaborator

gaearon commented Apr 10, 2018

Are you familiar with React data flow in general?

Typically instead of manually managing a list of children like this, your render method should have something like

let markers = [];

// fill these markers based on state
// ...
// and then render them

return <Gmaps>{markers}</Gmaps>

@maulberto3
Copy link

maulberto3 commented Apr 10, 2018

Actually yes, I am using that in my render.

Particularly, upon deciding what markers to render (due to the selected Dropdowns), I create small containers, i.e.:
const objMarkersElecCont = Object.values(this.state.obj1.markersElec);

Then, I let React conditionally render (because there may be markers or not on-screen), i.e.:
{Array.isArray(objMarkersElecCont) ? objMarkersElecCont : false}

Note that this.state.obj1.markersElec which was created inside the (now unsafe) componentWillreceiveProps(), all inside the same Map component.

I wish you could briefly go to http://crc-sen-maps.herokuapp.com/, select a few markers and click on them, just to get a feel of all of this: The Map component is always mounted, I am just modifying in the fly its children.

@gaearon
Copy link
Collaborator

gaearon commented Apr 10, 2018

I'd suggest not putting React elements into state. I think this would make the code clearer.

@maulberto3
Copy link

maulberto3 commented Apr 10, 2018

That is certainly happening here, and will try to follow your advice.

acdlite added a commit to acdlite/react that referenced this pull request Apr 10, 2018
The update queue is in need of a refactor. Recent bugfixes (facebook#12528) have
exposed some flaws in how it's modeled. Upcoming features like Suspense
and [redacted] also rely on the update queue in ways that weren't
anticipated in the original design.

Major changes:

- Instead of boolean flags for `isReplace` and `isForceUpdate`, updates
have a `tag` field (like Fiber). This lowers the cost for adding new
types of updates.
- Render phase updates are special cased. Updates scheduled during
the render phase are dropped if the work-in-progress does not commit.
This is used for `getDerivedStateFrom{Props,Catch}`.
- `callbackList` has been replaced with a generic effect list. Aside
from callbacks, this is also used for `componentDidCatch`.

TODO:

- [x] Class components
- [ ] Host roots
- [ ] Fix Flow
acdlite added a commit to acdlite/react that referenced this pull request Apr 10, 2018
The update queue is in need of a refactor. Recent bugfixes (facebook#12528) have
exposed some flaws in how it's modeled. Upcoming features like Suspense
and [redacted] also rely on the update queue in ways that weren't
anticipated in the original design.

Major changes:

- Instead of boolean flags for `isReplace` and `isForceUpdate`, updates
have a `tag` field (like Fiber). This lowers the cost for adding new
types of updates.
- Render phase updates are special cased. Updates scheduled during
the render phase are dropped if the work-in-progress does not commit.
This is used for `getDerivedStateFrom{Props,Catch}`.
- `callbackList` has been replaced with a generic effect list. Aside
from callbacks, this is also used for `componentDidCatch`.

TODO:

- [x] Class components
- [ ] Host roots
- [ ] Fix Flow
acdlite added a commit to acdlite/react that referenced this pull request Apr 11, 2018
The update queue is in need of a refactor. Recent bugfixes (facebook#12528) have
exposed some flaws in how it's modeled. Upcoming features like Suspense
and [redacted] also rely on the update queue in ways that weren't
anticipated in the original design.

Major changes:

- Instead of boolean flags for `isReplace` and `isForceUpdate`, updates
have a `tag` field (like Fiber). This lowers the cost for adding new
types of updates.
- Render phase updates are special cased. Updates scheduled during
the render phase are dropped if the work-in-progress does not commit.
This is used for `getDerivedStateFrom{Props,Catch}`.
- `callbackList` has been replaced with a generic effect list. Aside
from callbacks, this is also used for `componentDidCatch`.

TODO:

- [x] Class components
- [x] Host roots
- [ ] Fix Flow
acdlite added a commit to acdlite/react that referenced this pull request Apr 11, 2018
The update queue is in need of a refactor. Recent bugfixes (facebook#12528) have
exposed some flaws in how it's modeled. Upcoming features like Suspense
and [redacted] also rely on the update queue in ways that weren't
anticipated in the original design.

Major changes:

- Instead of boolean flags for `isReplace` and `isForceUpdate`, updates
have a `tag` field (like Fiber). This lowers the cost for adding new
types of updates.
- Render phase updates are special cased. Updates scheduled during
the render phase are dropped if the work-in-progress does not commit.
This is used for `getDerivedStateFrom{Props,Catch}`.
- `callbackList` has been replaced with a generic effect list. Aside
from callbacks, this is also used for `componentDidCatch`.

TODO:

- [x] Class components
- [x] Host roots
- [ ] Fix Flow
acdlite added a commit to acdlite/react that referenced this pull request Apr 11, 2018
The update queue is in need of a refactor. Recent bugfixes (facebook#12528) have
exposed some flaws in how it's modeled. Upcoming features like Suspense
and [redacted] also rely on the update queue in ways that weren't
anticipated in the original design.

Major changes:

- Instead of boolean flags for `isReplace` and `isForceUpdate`, updates
have a `tag` field (like Fiber). This lowers the cost for adding new
types of updates.
- Render phase updates are special cased. Updates scheduled during
the render phase are dropped if the work-in-progress does not commit.
This is used for `getDerivedStateFrom{Props,Catch}`.
- `callbackList` has been replaced with a generic effect list. Aside
from callbacks, this is also used for `componentDidCatch`.
rhagigi pushed a commit to rhagigi/react that referenced this pull request Apr 19, 2018
…acebook#12528)

Based on a bug found in UFI2.

There have been several bugs related to the update queue (and
specifically baseState) recently, so I'm going to follow-up with some
refactoring to clean it up. This is a quick fix so we can ship a
patch release.
Copy link

@Sompongyaya Sompongyaya left a comment

Choose a reason for hiding this comment

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

ยายเข้าSompongKarnsanga@gmail.com

acdlite added a commit to acdlite/react that referenced this pull request Apr 20, 2018
The update queue is in need of a refactor. Recent bugfixes (facebook#12528) have
exposed some flaws in how it's modeled. Upcoming features like Suspense
and [redacted] also rely on the update queue in ways that weren't
anticipated in the original design.

Major changes:

- Instead of boolean flags for `isReplace` and `isForceUpdate`, updates
have a `tag` field (like Fiber). This lowers the cost for adding new
types of updates.
- Render phase updates are special cased. Updates scheduled during
the render phase are dropped if the work-in-progress does not commit.
This is used for `getDerivedStateFrom{Props,Catch}`.
- `callbackList` has been replaced with a generic effect list. Aside
from callbacks, this is also used for `componentDidCatch`.
acdlite added a commit to acdlite/react that referenced this pull request Apr 21, 2018
The update queue is in need of a refactor. Recent bugfixes (facebook#12528) have
exposed some flaws in how it's modeled. Upcoming features like Suspense
and [redacted] also rely on the update queue in ways that weren't
anticipated in the original design.

Major changes:

- Instead of boolean flags for `isReplace` and `isForceUpdate`, updates
have a `tag` field (like Fiber). This lowers the cost for adding new
types of updates.
- Render phase updates are special cased. Updates scheduled during
the render phase are dropped if the work-in-progress does not commit.
This is used for `getDerivedStateFrom{Props,Catch}`.
- `callbackList` has been replaced with a generic effect list. Aside
from callbacks, this is also used for `componentDidCatch`.
acdlite added a commit that referenced this pull request Apr 23, 2018
* Decouple update queue from Fiber type

The update queue is in need of a refactor. Recent bugfixes (#12528) have
exposed some flaws in how it's modeled. Upcoming features like Suspense
and [redacted] also rely on the update queue in ways that weren't
anticipated in the original design.

Major changes:

- Instead of boolean flags for `isReplace` and `isForceUpdate`, updates
have a `tag` field (like Fiber). This lowers the cost for adding new
types of updates.
- Render phase updates are special cased. Updates scheduled during
the render phase are dropped if the work-in-progress does not commit.
This is used for `getDerivedStateFrom{Props,Catch}`.
- `callbackList` has been replaced with a generic effect list. Aside
from callbacks, this is also used for `componentDidCatch`.

* Remove first class UpdateQueue types and use closures instead

I tried to avoid this at first, since we avoid it everywhere else in the Fiber
codebase, but since updates are not in a hot path, the trade off with file size
seems worth it.

* Store captured errors on a separate part of the update queue

This way they can be reused independently of updates like
getDerivedStateFromProps. This will be important for resuming.

* Revert back to storing hasForceUpdate on the update queue

Instead of using the effect tag. Ideally, this would be part of the
return type of processUpdateQueue.

* Rename UpdateQueue effect type back to Callback

I don't love this name either, but it's less confusing than UpdateQueue
I suppose. Conceptually, this is usually a callback: setState callbacks,
componentDidCatch. The only case that feels a bit weird is Timeouts,
which use this effect to attach a promise listener. I guess that kinda
fits, too.

* Call getDerivedStateFromProps every render, even if props did not change

Rather than enqueue a new setState updater for every props change, we
can skip the update queue entirely and merge the result into state at
the end. This makes more sense, since "receiving props" is not an event
that should be observed. It's still a bit weird, since eventually we do
persist the derived state (in other words, it accumulates).

* Store captured effects on separate list from "own" effects (callbacks)

For resuming, we need the ability to discard the "own" effects while
reusing the captured effects.

* Optimize for class components

Change `process` and `callback` to match the expected payload types
for class components. I had intended for the update queue to be reusable
for both class components and a future React API, but we'll likely have
to fork anyway.

* Only double-invoke render phase lifecycles functions in DEV

* Use global state to track currently processing queue in DEV
bors bot referenced this pull request in mythmon/corsica-tree-status Apr 23, 2018
5: Update react monorepo to v16.3.2 r=mythmon a=renovate[bot]

This Pull Request renovates the package group "react monorepo".


-   [react-dom](https://github.com/facebook/react) (`dependencies`): from `16.2.0` to `16.3.2`
-   [react](https://github.com/facebook/react) (`dependencies`): from `16.2.0` to `16.3.2`

# Release Notes
<details>
<summary>facebook/react</summary>

### [`v16.3.0`](https://github.com/facebook/react/blob/master/CHANGELOG.md#&#8203;1630-March-29-2018)

##### React

* Add a new officially supported context API. ([@&#8203;acdlite] in [#&#8203;11818](`https://github.com/facebook/react/pull/11818`))
* Add a new `React.createRef()` API as an ergonomic alternative to callback refs. ([@&#8203;trueadm] in [#&#8203;12162](`https://github.com/facebook/react/pull/12162`))
* Add a new `React.forwardRef()` API to let components forward their refs to a child. ([@&#8203;bvaughn] in [#&#8203;12346](`https://github.com/facebook/react/pull/12346`))
* Fix a false positive warning in IE11 when using `React.Fragment`. ([@&#8203;XaveScor] in [#&#8203;11823](`https://github.com/facebook/react/pull/11823`))
* Replace `React.unstable_AsyncComponent` with `React.unstable_AsyncMode`. ([@&#8203;acdlite] in [#&#8203;12117](`https://github.com/facebook/react/pull/12117`))
* Improve the error message when calling `setState()` on an unmounted component. ([@&#8203;sophiebits] in [#&#8203;12347](`https://github.com/facebook/react/pull/12347`))
##### React DOM

* Add a new `getDerivedStateFromProps()` lifecycle and `UNSAFE_` aliases for the legacy lifecycles. ([@&#8203;bvaughn] in [#&#8203;12028](`https://github.com/facebook/react/pull/12028`))
* Add a new `getSnapshotBeforeUpdate()` lifecycle. ([@&#8203;bvaughn] in [#&#8203;12404](`https://github.com/facebook/react/pull/12404`))
* Add a new `<React.StrictMode>` wrapper to help prepare apps for async rendering. ([@&#8203;bvaughn] in [#&#8203;12083](`https://github.com/facebook/react/pull/12083`))
* Add support for `onLoad` and `onError` events on the `<link>` tag. ([@&#8203;roderickhsiao] in [#&#8203;11825](`https://github.com/facebook/react/pull/11825`))
* Add support for `noModule` boolean attribute on the `<script>` tag. ([@&#8203;aweary] in [#&#8203;11900](`https://github.com/facebook/react/pull/11900`))
* Fix minor DOM input bugs in IE and Safari. ([@&#8203;nhunzaker] in [#&#8203;11534](`https://github.com/facebook/react/pull/11534`))
* Correctly detect Ctrl + Enter in `onKeyPress` in more browsers. ([@&#8203;nstraub] in [#&#8203;10514](`https://github.com/facebook/react/pull/10514`))
* Fix containing elements getting focused on SSR markup mismatch. ([@&#8203;koba04] in [#&#8203;11737](`https://github.com/facebook/react/pull/11737`))
* Fix `value` and `defaultValue` to ignore Symbol values. ([@&#8203;nhunzaker] in [#&#8203;11741](`https://github.com/facebook/react/pull/11741`))
* Fix refs to class components not getting cleaned up when the attribute is removed. ([@&#8203;bvaughn] in [#&#8203;12178](`https://github.com/facebook/react/pull/12178`))
* Fix an IE/Edge issue when rendering inputs into a different window. ([@&#8203;M-ZubairAhmed] in [#&#8203;11870](`https://github.com/facebook/react/pull/11870`))
* Throw with a meaningful message if the component runs after jsdom has been destroyed. ([@&#8203;gaearon] in [#&#8203;11677](`https://github.com/facebook/react/pull/11677`))
* Don't crash if there is a global variable called `opera` with a `null` value. [@&#8203;alisherdavronov] in [#&#8203;11854](`https://github.com/facebook/react/pull/11854`))
* Don't check for old versions of Opera. ([@&#8203;skiritsis] in [#&#8203;11921](`https://github.com/facebook/react/pull/11921`))
* Deduplicate warning messages about `<option selected>`. ([@&#8203;watadarkstar] in [#&#8203;11821](`https://github.com/facebook/react/pull/11821`))
* Deduplicate warning messages about invalid callback. ([@&#8203;yenshih] in [#&#8203;11833](`https://github.com/facebook/react/pull/11833`))
* Deprecate `ReactDOM.unstable_createPortal()` in favor of `ReactDOM.createPortal()`. ([@&#8203;prometheansacrifice] in [#&#8203;11747](`https://github.com/facebook/react/pull/11747`))
* Don't emit User Timing entries for context types. ([@&#8203;abhaynikam] in [#&#8203;12250](`https://github.com/facebook/react/pull/12250`))
* Improve the error message when context consumer child isn't a function. ([@&#8203;raunofreiberg] in [#&#8203;12267](`https://github.com/facebook/react/pull/12267`)) 
* Improve the error message when adding a ref to a functional component. ([@&#8203;skiritsis] in [#&#8203;11782](`https://github.com/facebook/react/pull/11782`))
##### React DOM Server

* Prevent an infinite loop when attempting to render portals with SSR. ([@&#8203;gaearon] in [#&#8203;11709](`https://github.com/facebook/react/pull/11709`))
* Warn if a class doesn't extend `React.Component`. ([@&#8203;wyze] in [#&#8203;11993](`https://github.com/facebook/react/pull/11993`))
* Fix an issue with `this.state` of different components getting mixed up. ([@&#8203;sophiebits] in [#&#8203;12323](`https://github.com/facebook/react/pull/12323`))
* Provide a better message when component type is undefined. ([@&#8203;HeroProtagonist] in [#&#8203;11966](`https://github.com/facebook/react/pull/11966`))

---

### [`v16.3.1`](https://github.com/facebook/react/blob/master/CHANGELOG.md#&#8203;1631-April-3-2018)

##### React

* Fix a false positive warning in IE11 when using `Fragment`. ([@&#8203;heikkilamarko] in [#&#8203;12504](`https://github.com/facebook/react/pull/12504`))
* Prefix a private API. ([@&#8203;Andarist] in [#&#8203;12501](`https://github.com/facebook/react/pull/12501`))
* Improve the warning when calling `setState()` in constructor. ([@&#8203;gaearon] in [#&#8203;12532](`https://github.com/facebook/react/pull/12532`))
##### React DOM

* Fix `getDerivedStateFromProps()` not getting applied in some cases. ([@&#8203;acdlite] in [#&#8203;12528](`https://github.com/facebook/react/pull/12528`))
* Fix a performance regression in development mode. ([@&#8203;gaearon] in [#&#8203;12510](`https://github.com/facebook/react/pull/12510`))
* Fix error handling bugs in development mode. ([@&#8203;gaearon] and [@&#8203;acdlite] in [#&#8203;12508](`https://github.com/facebook/react/pull/12508`))
* Improve user timing API messages for profiling. ([@&#8203;flarnie] in [#&#8203;12384](`https://github.com/facebook/react/pull/12384`))
##### Create Subscription

* Set the package version to be in sync with React releases. ([@&#8203;bvaughn] in [#&#8203;12526](`https://github.com/facebook/react/pull/12526`))
* Add a peer dependency on React 16.3+. ([@&#8203;NMinhNguyen] in [#&#8203;12496](`https://github.com/facebook/react/pull/12496`))

---

### [`v16.3.2`](https://github.com/facebook/react/blob/master/CHANGELOG.md#&#8203;1632-April-16-2018)

##### React

* Improve the error message when passing `null` or `undefined` to `React.cloneElement`. ([@&#8203;nicolevy] in [#&#8203;12534](`https://github.com/facebook/react/pull/12534`))
##### React DOM

* Fix an IE crash in development when using `<StrictMode>`. ([@&#8203;bvaughn] in [#&#8203;12546](`https://github.com/facebook/react/pull/12546`))
* Fix labels in User Timing measurements for new component types. ([@&#8203;bvaughn] in [#&#8203;12609](`https://github.com/facebook/react/pull/12609`))
* Improve the warning about wrong component type casing. ([@&#8203;nicolevy] in [#&#8203;12533](`https://github.com/facebook/react/pull/12533`))
* Improve general performance in development mode. ([@&#8203;gaearon] in [#&#8203;12537](`https://github.com/facebook/react/pull/12537`))
* Improve performance of the experimental `unstable_observedBits` API with nesting. ([@&#8203;gaearon] in [#&#8203;12543](`https://github.com/facebook/react/pull/12543`))
##### React Test Renderer

* Add a UMD build. ([@&#8203;bvaughn] in [#&#8203;12594](`https://github.com/facebook/react/pull/12594`))

---


</details>

# Commits

<details>
<summary>facebook/react</summary>

#### v16.3.0
-   [`c2c3c0c`](facebook/react@c2c3c0cc36878cd6f020a480b83ff1c03b62fd28)Fix build script to handle react-is (no peer deps) (#&#8203;12471)
-   [`488ad5a`](facebook/react@488ad5a6b94ac4b71ff587ecde05e48a218aba62)Fix typo in create-subscription readme
-   [`c1b21a7`](facebook/react@c1b21a746c7d08554eed8bf55030a4049380c32c)Added DEV warning if getSnapshotBeforeUpdate is defined as a static method (#&#8203;12475)
-   [`268a3f6`](facebook/react@268a3f60dfe67c4f6439fc37b569a2d81c81a53a)Add unstable APIs for async rendering to test renderer (#&#8203;12478)
-   [`c44665e`](facebook/react@c44665e83278becfe7a3afdf788789536d63387b)Fix bug when fatal error is thrown as a result of `batch.commit` (#&#8203;12480)
-   [`7a833da`](facebook/react@7a833dad95b3059ebfdfba44d3fa68e1301d8e6a)setState() in componentDidMount() should flush synchronously even with createBatch() (#&#8203;12466)
-   [`5855e9f`](facebook/react@5855e9f2158b31d945f3fcc5bc582389dbecc88e)Improve warning message for setState-on-unmounted (#&#8203;12347)
-   [`15e3dff`](facebook/react@15e3dffb4c9ca9b9466f4ef1a6b8b2293d41e9d6)Don&#x27;t bail out on referential equality of Consumer&#x27;s props.children function (#&#8203;12470)
-   [`125dd16`](facebook/react@125dd16ba0b3fa74767b1cf417a3116a4a2b251a)Update user timing to record the timeout deadline with &#x27;waiting&#x27; events (#&#8203;12479)
-   [`96fe3b1`](facebook/react@96fe3b1be2fe74e83c9a25d7511f23dbef15ac99)Add React.isValidElementType() (#&#8203;12483)
-   [`53fdc19`](facebook/react@53fdc19df092bbc4bd736aea4ef8e0f12d692ee6)Updated react-is README to show new isValidElementType()
-   [`8650d2a`](facebook/react@8650d2a1357985958c2738da55ea349406482721)Disable createRoot for open source builds (#&#8203;12486)
-   [`6294b67`](facebook/react@6294b67a406d21cc6b65162e47497c1e8afe398f)unstable_createRoot (#&#8203;12487)
-   [`b2379d4`](facebook/react@b2379d4cbe82653da931ccb128916707bc53d28a)Updating package versions for release 16.3.0
-   [`9778873`](facebook/react@9778873143072635a795fec2ad0e1ac0bb7d8b91)Updating dependencies for react-noop-renderer
-   [`8e3d94f`](facebook/react@8e3d94ffa1d2e19a5bf4b9f8030973b65b0fc854)Update bundle sizes for 16.3.0 release

#### v16.3.1
-   [`2c3f5fb`](facebook/react@2c3f5fb97b6ea077f3e9aae6c6587bfe8328036d)Add React 16.3.0 changelog (#&#8203;12488)
-   [`4304475`](facebook/react@43044757e55eca13ae788056b59f94788fc15050)Fix links
-   [`18ba36d`](facebook/react@18ba36d89165ec15655f2606b0a6ba2e709ce641)Move context API in Changelog to &quot;React&quot; section
-   [`59b3905`](facebook/react@59b39056d91787f6a3e4e0dfc0825c8687bd0af9)Fix method name in changelog
-   [`fa8e678`](facebook/react@fa8e67893fca1b3902637129972032bca248a584)Change create-subscription&#x27;s peerDep on react to ^16.3.0 (#&#8203;12496)
-   [`0c80977`](facebook/react@0c80977061ba576cee9ae0891245be233929d2ed)Validate React.Fragment props without Map. (#&#8203;12504)
-   [`59dac9d`](facebook/react@59dac9d7a6a2f0b66003cf717d71b5587265423f)Fix DEV performance regression by avoiding Object.assign on Fibers (#&#8203;12510)
-   [`6b99c6f`](facebook/react@6b99c6f9d376bacbb769264d743c405b495b03ad)Add missing changelog item
-   [`7a27ebd`](facebook/react@7a27ebd52a3025a946c67eaf84d2646fd307cb44)Update user timing to record when we are about to commit (#&#8203;12384)
-   [`4ccf58a`](facebook/react@4ccf58a94dce323718540b8185a32070ded6094b)Fix context stack misalignment caused by error replay (#&#8203;12508)
-   [`6f2ea73`](facebook/react@6f2ea73978168372f33a6dfad6c049afddc4aef3)Extract throw to separate function so performUnitOfWork does not deopt (#&#8203;12521)
-   [`ba245f6`](facebook/react@ba245f6f9b0bf31c2ebff5c087c21bcae111e6c3)Prefix _context property on returned ReactContext from createContext - it&#x27;s private (#&#8203;12501)
-   [`eb6e752`](facebook/react@eb6e752cabafed0b72e1d0a38819ff156557d537)Bumped create-subscription package version (#&#8203;12526)
-   [`da4e855`](facebook/react@da4e85567b411a180c2cfa1ef6573cf3cc9257f1)Remove @&#8203;providesModule in www bundles (#&#8203;12529)
-   [`0f2f90b`](https://github.com/facebook/react/commit/0f2f90bd9a9daf241d691bf4af3ea2e3a263c0e3)getDerivedStateFrom{Props,Catch} should update updateQueue.baseState (#&#8203;12528)
-   [`36c2939`](facebook/react@36c29393720157a3966ce1d50449a33a35bdf14c)Improve not-yet-mounted setState warning (#&#8203;12531)
-   [`a2cc3c3`](facebook/react@a2cc3c38e214c16ff6805312d4353c1faab9ff95)Follow up: make new warning less wordy (#&#8203;12532)
-   [`2279843`](facebook/react@2279843ef966ea2e0460986efa1f91513cd50623)Updating yarn.lock file for 16.3.1 release
-   [`787b343`](facebook/react@787b343f674c72837209bdffd55c59682910d807)Updating package versions for release 16.3.1
-   [`dc05957`](facebook/react@dc059579c3e56ca338a999b86d146d2341ee6f64)Update bundle sizes for 16.3.1 release
-   [`b15b165`](facebook/react@b15b165e0798dca03492e354ebd5bcf87b711184)Changelog for 16.3.1

#### v16.3.2
-   [`1c2876d`](facebook/react@1c2876d5b558b8591feb335d8d7204bc46f7da8a)Add a build step to hoist warning conditions (#&#8203;12537)
-   [`5e3706c`](facebook/react@5e3706cca0fe0da462c771d14a271cd2961e5718)Don&#x27;t render bitmask-bailing consumers even if there&#x27;s a deeper matching child (#&#8203;12543)
-   [`e932e32`](https://github.com/facebook/react/commit/e932e321a88e07935224701bc4580e3dc9889afe)facebook.github.io/react -&gt; reactjs.org (#&#8203;12545)
-   [`d328e36`](facebook/react@d328e362e86a6af4a0664e004b8f97f18ce972c8)Removed duplicate typeof check (#&#8203;12541)
-   [`8ec0e4a`](facebook/react@8ec0e4a99df76c0ff1779cac4f2eaaaf35a6b5bb)Removed Array.from() usage (#&#8203;12546)
-   [`27535e7`](facebook/react@27535e7bfcb63e8a4d65f273311e380b4ca12eff)Clarify ReactDOM&#x27;s case warning for html tags (#&#8203;12533)
-   [`7a3416f`](facebook/react@7a3416f27532ac25849dfbc505300d469b43bbcc)Expose component stack from reactTag to React Native renderer (#&#8203;12549)
-   [`cf649b4`](facebook/react@cf649b40a56dc5c0ffe2595b963847f0ff8de245)Move TouchHistoryMath to React Native repo (#&#8203;12557)
-   [`5b16b39`](facebook/react@5b16b39508ec33f2f374a5a12aa71647e1728d08)Bug fix
-   [`6bf2797`](facebook/react@6bf2797d6cf76676791424afc93b76dd60d7074c)Remove flushSync from React Native (#&#8203;12565)
-   [`bc753a7`](facebook/react@bc753a716e185c31d8eb7404ab5dd6ee7467b7cb)Support findNodeHandle in Fabric (#&#8203;12573)
-   [`181747a`](https://github.com/facebook/react/commit/181747a6cc25f3020b8561f475eca4ad2824256b)[RN] Move takeSnapshot to RN (#&#8203;12574)
-   [`20c5d97`](facebook/react@20c5d97bb6c6a4af76d66a7e5134952989f9a9b2)Keep consistency in the comment (#&#8203;12579)
-   [`ea37545`](facebook/react@ea3754503742afc3d5c5de2140717817794870ec)Must be *a* before PlacementAndUpdate (#&#8203;12580)
-   [`76b4ba0`](facebook/react@76b4ba01290f446f4313adf3846954412c6051b8)Preserve error codes for invariants on www (#&#8203;12539)
-   [`8dfb057`](facebook/react@8dfb0578816435a1a72f04506ee20d3c55d0f9bc)Unfork invariant and instead use it from reactProdInvariant (#&#8203;12585)
-   [`f88deda`](facebook/react@f88deda83bab316385f39e8479850527cda90607)Throw more specific error if passed undefined in React.cloneElement (#&#8203;12534)
-   [`2f7bca0`](facebook/react@2f7bca0eb2487955e71a45e288e5847b5af522a5)Allocate unique reactTags for RN and Fabric (#&#8203;12587)
-   [`933f882`](facebook/react@933f882a9df728662befe558005f2ea3fe827a1d)Remove ReactNativePropRegistry (#&#8203;12559)
-   [`40d0772`](https://github.com/facebook/react/commit/40d07724fcc801ad69e17b295b68ebea753d5977)[RN] Remove unstable_batchedUpdates and unmountComponentAtNodeAndRemoveContainer from Fabric (#&#8203;12571)
-   [`b6e0512`](facebook/react@b6e0512a81524d397ff4fbfb892372ecc84c6b02)Consolidate eventTypes registry with view configs (#&#8203;12556)
-   [`b99d0b1`](https://github.com/facebook/react/commit/b99d0b14160150c566e091bd10b634beec9a58c3)[RN] Move view config registry to shims (#&#8203;12569)
-   [`725c054`](facebook/react@725c054d4d5d07c5c553a1ca724b01f2e6a43c5d)Refactor findHostInstance and findNodeHandle (#&#8203;12575)
-   [`52afbe0`](facebook/react@52afbe0ebb6fca0fe480e77c6fa8482870ddb2c9)createReactNativeComponentClass needs to be CommonJS
-   [`3eae866`](facebook/react@3eae866e03a96c4f46e257cba73ca158b049ab05)Fixes language in error message. (#&#8203;12590)
-   [`b846152`](facebook/react@b8461524db6d3e016fabf001ad8fa086b4918ef9)Added UMD build to test renderer package (#&#8203;12594)
-   [`3e9515e`](facebook/react@3e9515eedebe0c19f047391605c5b3c71d13fbc2)Remove @&#8203;providesModule in www shims
-   [`915bb53`](facebook/react@915bb5321a8db3435eb36ef1cf9414c15333b447)Bump expiration for interactive updates to 150ms in production (#&#8203;12599)
-   [`c27a998`](https://github.com/facebook/react/commit/c27a99812e75e73d9fad88c97ac8b8db452012c1)[Danger] Minor fixes (#&#8203;12606)
-   [`5dfbfe9`](facebook/react@5dfbfe9da740398c0a2cf4d897a0085000d06b7b)Fixed debug performance labels for new component types (#&#8203;12609)
-   [`1591c8e`](facebook/react@1591c8ebab6151f3cae59ad42e3c15acc52cd67b)Update GCC (#&#8203;12618)
-   [`a4cef29`](facebook/react@a4cef2970341c08e5c16a2406fbf532fc8053d12)tests: add regression test for reading ReactCurrentOwner stateNode (#&#8203;12412)
-   [`2e1cc28`](facebook/react@2e1cc2802709877fb2454163ba30e52a91feac8e)Fix small typos in create-subscription readme (#&#8203;12399)
-   [`1e97a71`](facebook/react@1e97a71a829e698ddac0a5e15fbdec97d35ed2bc)Fix documentation of the release process (#&#8203;12337)
-   [`66c44a7`](facebook/react@66c44a7bc34cb3fcb3c788dcce3f3345a5bd9f58)Updating yarn.lock file for 16.3.2 release
-   [`82f67d6`](facebook/react@82f67d65fd4584c4528352e6b9166ca4da282382)Updating package versions for release 16.3.2
-   [`6494f6b`](facebook/react@6494f6b6b8e1cfa5df9f72b4d94cf9ed582805cd)Update error codes for 16.3.2 release
-   [`3232616`](facebook/react@32326163480b5028ee16f6b4e4ea4426f3c5e95c)Update bundle sizes for 16.3.2 release
-   [`01402f4`](facebook/react@01402f4ad922b5467812586567519e9e5bbd595f)Add 16.3.2 changelog (#&#8203;12621)

</details>





---

This PR has been generated by [Renovate Bot](https://renovateapp.com).

Co-authored-by: Renovate Bot <bot@renovateapp.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants