What’s new in React 16.3(.0-alpha)

React 16.3-alpha just hit npmjs and can be downloaded and added to your project. What are the biggest, most interesting changes?

Update 05.02.2018 — I’ve previously made some wrong observation about the createContext behavior, this section was updated to reflect the actual behavior of the factory function.

New context API

Context API was always a thing of mystery — it’s an official, documented React API but at the same time developers warned us not to use it because the API might change with time, and it was missing some documentation on purpose. Well, that time is now — the RFC phase has passed and the new API is merged. It is definitely more “user friendly” and might make your life a bit easier when all you want is simple state management without the “overhead” of Redux or MobX.

The new API is accessible as React.createContext() and creates two components for us:

Creation of the new context via React.createContext

Calling the factory function will return us an object that has a “Provider” and a “Consumer” in it.

The “Provider” is a special component which aims to provide data to all components in its sub-tree, so one example of usage would be:

Usage of the new context API — Context.Provider

Here we select a sub-tree (in this case, the whole tree) to which we want to pass our “theme” context, and set the value we want to pass. The value can of course be dynamic (e.g. based on this.state).

Next step is to use the Consumer:

Usage of the new context API — Context.Consumer

If you happen to render the “Consumer” without embeding it in a corresponding “Provider”, the default value declared at createContext call will be used.

Please notice some things:

  • the consumer must have access to the same Context component — if you were to create a new context, with the same parameter as input, a new Context would be created and the data would not be passed. For this reason please consider Context a component — it should be created once and then exported + imported whenever needed
  • the new syntax uses the function as child (sometime called render prop) pattern — if you’re not familiar with this pattern I recommend reading some articles on it
  • it is no longer required to use prop-types to specify contextProps if you want to make use of the new Context API

The data from the context passed to the function matches the value prop set in the providers Context.Provider component, and altering the data in the Provider will cause all consumers to re-render.

New life-cycle methods

The other RFC to make it into the alpha release concerns deprecation of some life-cycle methods and introduction of one (four) new.

This change aims to enforce best practices (you can read up on why those functions can be tricky in my article on life-cycle methods) which will be very crucial once the asynchronous rendering mode (which was one of React 16 “Fiber” main goals) will be fully activated.

The functions that will be in time considered deprecation are:

  • componentWillMount — please use componentDidMount instead
  • componentWillUpdate — please use componentDidUpdate instead
  • componentWillReceiveProps — a new function, static getDerivedStateFromProps is introduced

Do not be alarm, you are still able to use those functions — the depracation notices are slotted for 16.4 and removal of them is planned in 17.0

Everyone panics. Dan says not to panic. Some people still panic.

You will only see the deprecation notices if you also opt in into the new StrictMode or AsyncMode in which case you can still suppress them by using:

  • UNSAFE_componentWillMount
  • UNSAFE_componentWillReceiveProps
  • UNSAFE_componentWillUpdate

static getDerivedStateFromProps

As componentWillReceiveProps gets removed, we need some means of updating the state based on props change — the community decided to introduce a new — static — method to handle this.

What’s a static method? A static method is a method / function that exists on the class not its instance. The easiest difference to think about is that static method does not have access to this and has the keyword static in front of it.

Ok, but if the function has no access to this how are we to call this.setState? The answer is — we don’t. Instead the function should return the updated state data, or null if no update is needed:

Using getDerivedStateFromProps in order to update state

The returned value behaves similarly to current setState value — you only need to return the part of state that changes, all other values will be preserved.

Things to keep in mind:

Remember to init state!

You still need to declare the initial state of the component (either in constructor or as a class field).


getDerivedStateFromProps is called both on initial mounting and on re-rendering of the component, so you can use it instead of creating state based on props in constructor.


Error, please use just getDerivedStateFromProps

If you declare both getDerivedStateFromProps and componentWillReceiveProps only getDerivedStateFromProps will be called, and you will see a warning in the console.


Usually, you would use a callback to make sure some code is called when the state was actually updated — in this case, please use componentDidUpdate instead.


If you prefer not to use the static keyword, you can use the alternative syntax:

Declare getDerivedStateFromProps without using static

StrictMode

Strict mode is a new way to make sure your code is following the best practices. It’s a component available under React.StrictMode and can be added to your application tree or subtree:

Usage of the ‘use strict’ … I mean StrictMode

If one of the children components, rendered in the StrictMode subtree uses some of the method mentioned in previous paragraphs (like componentWillMount) you will then see an error message in browser console when running an development build:

Error: unsafe lifecycle in StrictMode subtree

Currently the error message points to the RFC for the life-cycle methods removal.

AsyncMode

The not-yet-active async Component support was renamed to be aligned with the StrictMode and is now available under React.unsafe_AsyncMode. Using it will also activate StrictMode warnings.

If you want to learn more about asynchronous components you might check some articles / examples at:

New version of React Developer Tools

Additionally, a new version of the Developer Tools was released to support debugging the new components.

If you’re using Chrome — you might need to wait a bit more, as it’s not updated yet in the store, and trying to debug results in … interesting results:

React. __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED is still better

Firefox users should be able to make use of the new features already:

New AsyncComponent is visible in the Firefox Developer Tools

More to come?

Please keep in mind that this is an alpha release and the stable 16.3 might have more / fewer changes. That said, according to Dan, 16.3 should be released “sometime nex week”:

Last’s week next week is this week.