Before you’re going to hate it, then you’re going to love it.

Concurrent Render(throughout 16)

In JSConf Iceland ’18, Dan God mentioned Concurrent Render involving both CPU and IO.

Time Slicing means solving problems on the left, Suspense means solving problems on the right. What they collectively address is to improve the user experience and make it interactive in more scenarios. The Fiber architecture is the cornerstone of both.

Time Slicing

In versions prior to 16, the rendering process can be imagined as a one-time 30-meter dive, during which nothing else can be done (Stack Reconciler);

Pain point summary:

  • Render to the end once
  • Unable to adjust the sequence of higher priority events

Taking the diving example above as an example, it is now possible to dive 10 meters at a time in 3 chunks; Chunks are connected to each other through linked lists. A task with a higher priority is inserted between chunks, and the previous task is discarded.

After Fiber is enabled, the method of retrieving asynchronous data should be placed in the lifecycle hooks (Phase 2) after Render, since the lifecycle hooks (Phase 1) before Render are executed multiple times

Note: the rendering time of the original component is not reduced (or even increased), but the user feels smoother.

RequestIdleCallback (): With this API, the browser can handle low-priority tasks in idle time.

Suspense (16.6, 16.8, 16.9)

Suspense means to be able to pause rendering of the current component and continue rendering when something is done.

  • Code Splitting (16.6, online): Lazy file loading. The previous implementation was react-loadable
  • Concurrent mode (16.8, Q2 2019): Lazy file loading while doing other interactions;
  • Data fetching(version 16.9, mid-2019): Dynamic data fetching;
import React, { lazy, Suspense } from 'react'
const OtherComponent = lazy((a)= > import('./OtherComponent'))

function MyComponent() {
  return (
    <Suspense fallback={<div>loading...</div>} ><OtherComponent />
    </Suspense>)}Copy the code

For a simple idea of preloading, see Preload

const OtherComponentPromise = import('./OtherComponent');
const OtherComponent = React.lazy((a)= > OtherComponentPromise);
Copy the code

Render New return type

Render () added a number of return types to Render () in Act16. The following return types are supported so far:

  • React elements.
  • Arrays and fragments.
  • Portals.
  • String and numbers.
  • Booleans or null.

render

Render () supports returning Arrays to save one parent, as shown below:

const renderArray = () => [
  <div key="A">A</div>
  <div key="B">B</div>
]
Copy the code

Render () supports returning arrays similar to Fragments(16.2), which can be used without writing keys.

Portals

Render the React child node to the specified node

Example: Implement a Modal component, demo

As for the phenomenon of Portals bubbling to the parent’s sibling, demo, I think it can be implemented like this: If the component returns a Portal object, copy the event on the parent of the component to that component. It doesn’t actually bubble up to the sibling of the parent.

Error Boundaries

React 16 provides a new error-catching hook componentDidCatch(Error, errorInfo) that traps errors thrown by a child component during its life cycle, preventing global crashes. demo

ComponentDidCatch does not catch the following errors

  • Errors thrown by the event mechanism (errors in the event do not affect rendering)
  • Error Boundaries Errors thrown by yourself
  • An error occurred asynchronously
  • Server side rendering

Server side rendering

Server rendering is usually used as an optimization of last resort, so here’s a primer on how React 16 optimizes it.

The React 16 version introduced react.hydrate (), which waterfloods relevant events into HTML pages and compares the HTML generated by the front end with the HTML text that the server sends to the front end. If the two are inconsistent, replace the text content generated by the front end with the text content generated by the server (ignoring the attribute).

Custom attributes are supported

In The React 16 version, custom attributes are supported (data-xxx is recommended), so React can maintain a whitelist of attributes less. This is also a significant factor in reducing the size of React 16.

The Context (16.3, 16.6)

Context uses global in a componentized way, sharing global information about authenticated users, preferred language (internationalization), and so on, rather than passing it through layers of components.

Here are some more redundant passes:

<Page riderId={riderId} />
// ... which renders ...
<RiderDetail riderId={riderId} />
// ... which renders ...
<RiderLevel riderId={riderId} />
// ... which renders ...
<Avatar riderId={riderId} />
Copy the code


itself (Component Composition idea) can be passed before Context as follows:

function Page(props) {
  const avatar = <Avatar riderId={props.riderId} />
  return <RiderDetail avatar={avatar} />
}

<Page riderId={riderId} />
// ... which renders ...
<RiderDetail avatar={avatar} />
// ... which renders ...
<RiderLevel avatar={avatar} />
// ... which renders ...
{ props.avatar }
Copy the code

Here is an example of writing using Context as follows:

const RiderContext = React.createContext(1) // This is the default value

function Page(props) {
  const riderId = props.riderId
  return( <RiderContext.Provider value={riderId}> <RiderDetail /> </RiderContext.Provider> ) } function RiderDetail() { return <RiderLevel /> } class RiderLevel extends React.Component { static contextType = RiderContext render() { return <Avatar avatar={this.context} />; }}Copy the code

New Life Cycle (16.3)

In future 17, the following lifecycle hooks will be removed:

  • componentWillMount()The API was removed for two reasons:
    • Server render: Executing render immediately after componentWillMount execution causes methods executed in componentWillMount (fetching data, subscribing events) to not be executed.
    • Concurrent Render: In Fiber, the hook before Render is called multiple times, executing the subscription event in componentWillMount causes a memory leak;

ComponentDidMount (componentWillMount, componentDidMount, componentWillMount);

  • componentWillReceiveProps(nextProps)The API was removed based on the following considerations:
    • The semantics don’t quite fit logic

Here’s an example: For example, whenever you switch a TAB, you need to retrieve the data from the current page, which is usually the case:

componentWillReceiveProps(nextProps) {
  if(nextProps.riderId ! = =this.props.riderId) {
    fetchData()
  }
}
Copy the code

The new hook getDerivedStateFromProps() is puter. All it does is compare the newly passed property to the current state value, and update the current state if they are inconsistent. Before componentWillReceiveProps () to get the data logic mentioned in Concurrent render should also mentioned the rear to componentDidUpdate ().

getDerivedStateFromProps(nextProps, prevState) {
  if(nextProps.riderId ! == prevState.riderId) {return {
      riderId: nextProps.riderId
    }
  }
  // Return null to indicate that state is not used for updates
  return null
}
Copy the code
  • componentWillUpdate(): Currently understood as andcomponentWillMountSame thing

In React 16.3, there are two new life cycles:

  • GetDerivedStateFromProps (nextProps prevState) : more semantic, used to replace componentWillMount () and componentWillReceiveProps (nextProps);

  • GetSnapshotBeforeUpdate (prevProps, prevState): You can pass the result returned by this hook into the third parameter of componentDidUpdate to achieve DOM data unity. Instead of componentWillUpdate();

Update on Async Rendering

The React. Memo (16.6)

React.memo is a higher-order component that gives stateless components shouldComponentUpdate() and PureComponent capabilities in stateful group values.

const MyComponent = React.memo(function MyComponent(props) {... })Copy the code

Hooks (16.7)

Prior to React 16.7, React had two forms of components, stateful components (classes) and stateless components (functions). Hooks are used to enable previously stateless components to become stateful. This is more in line with the functional programming espoused by React.

Next, I’ll review the two core apis of Hooks, useState and useEffect

useState

UseState returns the status and a function that updates the status

const [count, setCount] = useState(initialState)
Copy the code

Using Hooks is more intuitive and concise than using class

function App() {
  const [count, setCount] = useState(0)

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={()= > setCount(count + 1)}>
        Click me
      </button>
    </div>)}Copy the code

useEffect(fn)

This hook is executed after each render. Think of it as a componentDidMount, componentDidUpdate, componentWillUnmount. Therefore, the advantages of using useEffect are as follows:

  1. Can be avoidedComponentDidMount, componentDidUpdateWriting repetitive code;
  2. You can write the association logic into oneuseEffect; (in the old days it had to be written in different life cycles);

The future of the React

This year’s React Conf shows how React has been on a steady upward trajectory since its inception, knocking Jquery off its throne at this point in 2018. React still has a long way to go.

A link to the

  • reactjs.org