React 17 is coming. It’s a very special edition


Write it at the front

React recently released v17.0.0-rc.0, nearly three years after the last big version of V16.0 (released on September 27, 2017)

Compared with react 16 and its previous versions, react 17 is very special——There are no new features

React v17.0 Release Candidate: No New Features

More Than This,Seven breaking changes have been brought along……

1、 Is there really no new feature?

What is the official position of react for V17The main goal of the first version of the technical transformation is to reduce the upgrade cost of the subsequent version

This release is primarily focused on making it easier to upgrade React itself.

Therefore, V17 is just a foreshadowing. We don’t want to release major new features, but for v18, v19 Later versions can be upgraded more smoothly and quickly

When React 18 and the next future versions come out, you will now have more options.

However, some of them had to break the backward compatibility, so we proposed a big version change of V17, and by the way, we took a ride to unload some historical burdens accumulated over two years

2、 Incremental upgrades are possible

Before V17, different versions of react could not be mixed(the event system will have problems). Therefore, developers either use the old version, or make great efforts to upgrade to the new version. Even some long tail modules that have no requirements all year round have to adapt and regression test as a whole. Considering the upgrade and adaptation cost of developers, the react maintenance team is also in a bind. They dare not drop the discarded API easily. They either maintain it for a long time or even endlessly, or choose to give up those old applications

And react 17 offers a new option——Progressive upgrade, allowing multiple versions of react to coexist, which is very friendly to large front-end applications. For example, pop-up components and long tail pages under some routes can be smoothly transferred to the new version one by one without upgrading (refer to the official demo)

P. Note that loading multiple versions of react (on demand) has significant performance overhead and should also be considered carefully

Multi version coexistence and micro front end architecture

The coexistence of multiple versions and the mixed use of old and new make it possible for micro front-end architecture to realize the expected gradual reconfiguration

It is possible to gradually upgrade, update and even rewrite some front-end functions

Compared with react, which supports the coexistence of multiple versions and completes the version upgrade step by step,Micro front end is more concerned about allowing different technology stacks to coexist and smoothly transition to the upgraded architecture, which solves a wider problem

On the other hand, it is also necessary to reflect on the micro front end when the problem of multi version mixing under the react technology stack no longer exists

  • Is it more appropriate to solve some problems by the technology stack itself?
  • Is coexistence of multi technology stacks normal or short-term transition?
  • Is there a lighter solution for the short-term transition?

For more thoughts on what problems micro front end is solving, see why micro frontends?

3、 7 breaking changes

The event delegate is no longer attached to the document

The main problem with the coexistence of previous versions is thatDefault delegation mechanism of react event systemFor performance reasons, react only givesdocumentAfter the DOM event is triggered, it will bubble todocument, react finds the corresponding component, creates a react event (synthetic event), and simulates the event bubble according to the component tree (at this time, the native DOM event has already appeared)documentYou’ve got to:

React 17 is coming. It's a very special edition

Therefore, when different versions of react components are nested,e.stopPropagation()Does not work properly (two different versions of the event system are independent, both todocumentIt’s too late.)

If a nested tree has stopped propagation of an event, the outer tree would still receive it.

P. As a matter of fact, atom encountered this problem in the early years

To solve this problem,React 17documentHang the event delegate to the DOM container instead

React 17 is coming. It's a very special edition

For example:

const rootNode = document.getElementById('root');
//Think of render as an example
ReactDOM.render(<App />, rootNode);
//The same is true for portals
// ReactDOM.createPortal(<App />, rootNode)
//React 16 event delegate (hung on document)
//React 17 event delegate (hung on DOM container)

On the other hand, the event system is transformed fromdocumentRetraction also makes it easier for react to coexist with other technology stacks (at least with less difference in event mechanism)

Move towards browser native events

In addition, the react event system has made some small changes to make it closer to the browser’s native events

  • onScrollNo more bubbles
  • onFocus/onBlurDirect adoption of nativefocusin/focusoutevent
  • In the capture phase, the native DOM event monitoring mechanism is used directly

be careful,onFocus/onBlurThe lower layer implementation scheme switching does not affect bubbling, that is, in reactonFocusIt’s still bubbling (and I’m not going to change it. I think it’s useful)

DOM event reuse pool discarded

For performance reasons, aEvent pool, which causes react events to be available only during propagation, and will be immediately recycled and releasedFor example:

<button onClick={(e) => {
    //Output button
    // e.persist();
    setTimeout(() => {
      //Error: cannot read property 'nodeName' of null
  Click Me!

All States on event objects outside the propagation process are set tonull, unless manuallye.persist()(or do value caching directly)

React 17 removes the event reuse mechanismBecause in the modern browser, this kind of performance optimization is meaningless, but it brings trouble to developers

Effect hook cleanup operation changed to asynchronous execution

Useeffect itself is executed asynchronously, butThe cleanup is synchronous(just like the class componentcomponentWillUnmountSynchronous execution is the same as that of synchronous execution), which may slow down cutting scenes such as tab. Therefore, react 17 is changed to perform cleaning work asynchronously

useEffect(() => {
  // This is the effect itself.
  return () => {
    //Before synchronous execution, after react 17 changed to asynchronous execution
    // This is its cleanup.

At the same time, it also corrects the execution order of the cleaning function, which is executed according to the order on the component tree (the order was not strictly guaranteed before)

P. S. for some special scenes that need synchronous cleaning, you can use layouteffect hook instead

Render returns undefined error

Render returns in reactundefinedWill report error:

function Button() {
  return; // Error: Nothing was returned from render

The original intention is to forget to writereturnThe common errors of the

function Button() {
  // We forgot to write return, so this component returns undefined.
  // React surfaces this as an error instead of ignoring it.
  <button />;

In subsequent iterations, it didn’tforwardRefmemoCheck it and add it in react 17. After that, whether the class component, functional component, orforwardRefmemoCheck where you expect to return the react componentundefined

P. S. empty components can be returnednullDoes not trigger an error

“Call stack” of component with error information disclosure

In the 16 cases of react, the “call stack” of the component can be revealed when encountering the error. However, there is still a big gap compared with the error stack of JavaScript

  • The source code location (file name, row and column number, etc.) is missing, and the console cannot click to jump to the wrong place
  • Cannot be used in a production environment(displayNameCrushed)

React 17 adopts a new component stack generation mechanism,It can achieve the effect of JavaScript native error stack (jump to source code), and it is also suitable for production environmentThe general idea is to rebuild the component stack when an error occurs, raise a temporary error within each component (do once for each component type), and thenerror.stackThe key information is extracted to construct the component stack

var prefix;
//Construct "call stack" of built-in components such as div
function describeBuiltInComponentFrame(name, source, ownerFn) {
  if (prefix === undefined) {
    // Extract the VM specific prefix used by each line.
    try {
      throw Error();
    } catch (x) {
      var match = x.stack.trim().match(/\n( *(at )?)/);
      prefix = match && match[1] || '';
  } // We use the prefix to ensure our stacks line up with native stack frames.

  return '\n' + prefix + name;
//And describenatecomponentframe is used to construct the "call stack" of class and functional components
//It's too long. I'm interested in reading the source code

becauseThe component stack is generated directly from the JavaScript native error stackSo you can click to jump back to the source code, and in the production environment, you can also press sourcemap to restore it

P. S. in the process of rebuilding the component stack, render and the constructor of the class component will be re executed. This part belongs to breaking change

P. S. for more information on rebuilding component stacks, see build component stacks from native stack frames, and react / packages / shared / reac tComponentStackFrame.js

Some of the exposed private APIs were removed

React 17 has deleted some private APIs, most of which were originally exposed to react native for web. At present, the new version of react native for web no longer relies on these APIs

In addition, when modifying the event system, it can be easily deletedReactTestUtils.SimulateNativeTool method, because its behavior is inconsistent with semantics, it is recommended to use react testing library instead

4、 Summary

In short, react 17 is a foreshadowing. The core goal of this version is to enable react to be upgraded gradually, so the biggest change isAllow multi version mixing to prepare for the smooth implementation of new features in the future

We’ve postponed other changes until after React 17. The goal of this release is to enable gradual upgrades.

reference material

  • React v17.0 Release Candidate: No New Features

It’s good to have gains and doubts

Focus on the front end back WeChat official account, and you will get a series of “use”.heart“Original” high-quality technical articles, including but not limited to the front-end Node.js And server technology

This paper was first published in Link to the original text:…

Recommended Today

IOS transfers value to JS class

IOS transfers value to JS class class class Scene: Web games written with cocos creator need to be connected to the app. Try and difficulty: 1. Baidu’s IOS and JS call each other and pass value to each other. The web side is written with JS native, while the code of Cocos creator is the […]