React lifecycle

In previous React versions, if you had a complex composite component and changed the state of the uppermost component, the call stack could be very long, and complicated operations in the middle could block the main thread for a long time, leading to a poor user experience. React Fiber was born.

Fiber is essentially a virtual stack frame that the new scheduler schedules freely according to priority, changing the previous synchronous rendering to asynchronous rendering and counting updates in segments without affecting the experience.

React how to prioritize: For things like animations that need to be rendered in real time for 16 ms, React will pause the update every 16 ms to come back and continue rendering the animation.

Asynchronous rendering has two stages: reconciliation, which can be interrupted, and COMMIT, which cannot be suspended and updates the interface until it is finished.

The life cycle of a component can be divided into three states:

  • Mounting: The real DOM is inserted
  • Updating: Being rerendered
  • Unmounting: The real DOM has been removed

Lifecycle approach

Constructor()

React borrows the constructor class as the initialization hook. Since we only allow arguments to be passed to components in certain ways, the constructor arguments are actually specified by React. React specifies that constructor takes three arguments, namely props, context, and updater.

  • Props is an attribute, which is immutable.
  • Context is the global context.
  • A updater is an object that contains some update methods

Enclosing setState final call is enclosing updater. EnqueueSetState method, enclosing forceUpdate final call is this updater. EnqueueForceUpdate method, So these apis are mostly used internally in React, exposed for developers to use in a rainy day.

In React, since all class components inherit from the Component or PureComponent class, the constructor method needs to be called first to get this, just as with the native class. The best practice for the Constructor lifecycle hook is to initialize this.state here.

Of course, you can use a property initializer instead, as follows:

import React, { Component } from 'react';
class App extends Component {
    state = {name: 'biu'}; }export default App;Copy the code

What about setState? (I said why setState here, the interviewer said if someone is so hands owe? HHH)

SetState is invalid, setState(…) Mounted or mounting components are updated only. Constructor: The component does not mount or mount mounting, so an error is reported and setState is ignored.

Reconciliation Stage (interruptible)

componentWillMount()

Called before the component is mounted into the DOM (before rendering), on the client side as well as on the server side rendering SSR

Don’t request data here: componentWillMount and mount are executed synchronously, meaning the hook is mounted immediately after execution. Requests to the server for data are performed asynchronously. Therefore, no matter how fast the request is, it should be processed after the synchronization task, that is, it is never possible to insert the requested data into the element and mount it together. (Call asynchronous Ajax requests in didMount)

componentWillReceiveProps(newProps)

Called when the component receives a new prop, initialization is not triggered.

  • The component receives the new property.
  • The component does not receive new properties, but the current component is being rerendered due to the parent component’s rerendering.

shouldComponentUpdate (nextProps, nextState)

Returns a Boolean value that determines whether to update and is used to optimize performance (true by default). Called when the component receives new props or state. Not called during initialization or when forceUpdate is used. This can be used when you are sure that you do not need to update the component. PureComponent shouldComponentUpdate()

Note: It can be used for components that change less, because if a component changes more often, you don’t have to waste time trying to figure out for yourself, In components such as father after setstate would call the parent component render subcomponents are to update But some children may not have used the parent component’s state Or rarely change is part of the state, is invoked shouldComponentUpdate Settings let him not to update

componentWillUpdate(nextProps, nextState)

Called when the component receives new props or state (shouldComponentUpdate returns true/ when calling this.forceUpdate()) but has not yet rendered, not when initialized. (Be careful with setState(), may loop indefinitely)

Note: Except shouldComponentUpdate, the other three are being phased out and given the individual name UNSAFE_componentWillXXX

render()

When building an abstract UI (an element to mount to the DOM), never call this.setState in the Render lifecycle hook, because this.setState will throw Render into an infinite loop.

Commit phase (update until complete)

componentDidMount()

Called after the first rendering, only on the client side.

The virtual DOM object returned by the Render method is used to create the real DOM structure, after which the component has generated the corresponding DOM structure, which can be accessed via this.getDomNode (). If you want to work with other JavaScript frameworks, you can use this method to call setTimeout, setInterval, or send AJAX requests for data.

Why data is requested here:

The requested data is usually loaded into the corresponding DOM, and the results of the asynchronous request are not available before the first rendering. If state is not set to the initial value of the received data attribute (constructor: this.state is set to the initial value of the /defaultProps is set to the initial props of the subcomponent), map is undefined. Empty data is also rendered at least once.

Requesting data here in didmount makes it more clear that the above process is:

First render the request to obtain data, according to the data obtained setState render again to load data into the DOM.

Data is not requested in willmount because:

Willmount is being deprecated, and since fiber can be repeated, both server and client will do it once, didmount will only do it on client.

componentDidUpdate (nextProps, nextState, snapshot)

Called immediately after the component finishes updating. Not called on initialization (careful with setState())

componentWillUnmount

Called immediately before the component is removed from the DOM. All native event listeners, subscribers, and timers used in the react component are destroyed here


Since the Reconciliation phase can be interrupted, life cycle functions executed during the Reconciliation phase can be called multiple times, causing bugs. As a result, several functions called in the Reconciliation phase should be avoided except shouldComponentUpdate, and a new API was introduced in V16 to address this issue.

Solution (new approach introduced)

getDerivedStateFromProps(nextProps, prevState)

Used to replace componentWillReceiveProps, this function can be in the initialization and is invoked when the update, according to the parent component of props according to need to update their state (derivative state). The object returned is the state to increment.

It is designed to be static, so that the developer can’t access this, which is the instance, and can’t call instance methods or setsState in it. The purpose is to keep the method pure. It is used to define derived state, and should not do anything else in it.

class ExampleComponent extends React.Component {
// Initialize state in constructor,
// Or with a property initializer.
    state = {};
    static getDerivedStateFromProps(nextProps, prevState) {
        if(prevState.someMirroredValue ! == nextProps.someValue) {return {
                derivedData: computeDerivedState(nextProps),
                someMirroredValue: nextProps.someValue};
            }
    // Return null to indicate no change to state.
        returnnull; }}Copy the code

GetSnapshotBeforeUpdate (prevProps, prevState)

    Replaces componentWillUpdate, which is called after the UPDATE and before the DOM update to read the latest DOM data. The returned value will be received by the third parameter of componentDidUpdate, we can use this channel to save some states that do not need persistence, and can be discarded after use. Some states, such as the web scrolling position, I do not need it to persist, only need to be able to restore the original position after component update.

    componentDidCatch(err,info)

      It is mainly used to catch errors and deal with them, so its usage is also special.

      Customize an ErrorBoundary component with only componentDidCatch lifecycle hooks that does one thing: display an error message if an error is caught, and a child component if no error is caught. Render the component that needs to catch the error as a sub-component of ErrorBoundary. Once the sub-component throws an error, the whole application will still not crash, but will be caught by ErrorBoundary.


      References:

      Juejin. Cn/post / 684490…

      Daveceddia.com/where-fetch…