Fun with Reactjs Part 4-Components (Life Cycle)

I. Introduction

     The previous article mainly introduced the creation mode of Reactjs components, and learned the basic knowledge and usage of state and props. This article will focus on the life cycle of Reactjs. This is very important for us to understand the implementation principle of Reactjs and use hook functions correctly.

   Reactjs used the life cycle of the old version before the V16.3 version, and then enabled the new version of the life cycle. The V17 version will completely discard the old version. We will introduce both versions.

Second, the old version

     The Reactjs life cycle includes three scenarios: mounting, updating, and unmounting. Each scenario provides related hook functions in different states. We can use these hook functions to implement custom functions.

The schematic diagram of the life cycle hook function timing is as follows:

1. When mounting (Mounting)

The process executed when the Reactjs component is first loaded, constructor-> componentWillMount-> render-> componentDidMount.

  • constructor

Call timing: The constructor will be called before the component is mounted.

The role of the hook: We also mentioned in the previous article that in the construction method, the following two things are mainly done:

(1) Initialize the state, here is the only place that can be initialized with this.state, other places can only be updated with setState.

(2) The method binding instance defined in the component. The previous article also mentioned that if you do not use the arrow function to define the method, you must bind this in the constructor.

If you do not need to use the above two points, you can not define the component's constructor.

Function example: The example is as follows:

constructor(props){
        // 1、调用父类构造方法
        super(props);
        //2、初始化state对象
        this.state = {hotItem:['口罩','手套','酒精',]};
        //绑定this
        this.changeHot = this.changeHot.bind(this);
}
  • componentWillMount (Abandoned soon)

The method is about to be abandoned, you can use React 17 version, but it will conflict with the new component life cycle hook function, it is recommended not to use.

Call timing: Call before calling render ().

The role of hooks: calling setState in this method will not trigger additional rendering, so it is a common mistake to request external data in this method and reduce one render. In general, this method does not have much effect.

  • render

Call timing: This method will be called for rendering when it is first mounted and updated.

The role of the hook: The render method is the only method that needs to be implemented in the class component. In this hook method, React JSX is rendered as a DOM node and mounted in the DOM tree.

The render function should be pure, which means that the state of the component should not be changed. Each call should return the same result, and it will not directly interact with the browser.

Function example: The implementation form of the method, we also introduced in the previous article, such as App.js, the example is as follows:

render(){
    return (
    <div className="App">
      {/* 引入组件 */}
      <SearchBox changeSearchVal = {this.changeSearchVal}/>
      <SearchHot />
      <SearchList searchListVal={this.state.searchListVal}>
        <div>为您搜索到2条记录</div>
      </SearchList>
    </div>
    );
  }
  • componentDidMount

Calling timing: after executing the render function (the DOM node has been created and mounted into the DOM number (the number of nodes inserted into the DOM)), it is executed immediately.

The role of the hook: The following operations can be performed in componentDidMount:

(1) Request network data, and call setState to update, it will trigger an additional rendering, but it will happen before the browser refreshes the screen. This ensures that even if render () will be called twice in this case, the user will not see the intermediate state

(2) Get DOM nodes through ref, get DOM attributes or manipulate DOM.

Function example: In App.js, we add componentDidMount method, get the default search list in the hook function, so that after the first loading is completed, the page displays the default list.

componentDidMount(){
    console.log("App componentDidMount");
    fetch("http://localhost:3000/search.json",{
      method:'GET',
    }).then(response => response.json())
    .then((data)=>{
      this.setState({searchListVal:data.search});
    })
  }

2. When updating (Updateing)

After the mounting is completed, when the props passed into the parent component and the state value in the component changes, the update time process will be triggered. componentWillReceiveProps-> shouldComponentUpdate-> componentWillUpdate-> render-> componentDidUpdate

  • componentWillReceiveProps (nextProps) (Abandoned soon)

This hook function will be deprecated in React 17 version.

Call timing: It is called before the mounted component receives new props.

The role of the hook: when the new attribute is received, the new and old Props are compared by if. This method is used to  this.setState() perform state conversion. This is similar to the new version of getDerivedStateFromProps.

  • shouldComponentUpdate(nextProps,nextState)

Call timing: After props or state changes, this hook function is called before render is called. The parent component updates prop, or calls setState will trigger. However, this method is not triggered by the first mount and forceUpdate.

The role of the hook: This function can decide whether to continue rendering (whether to execute the render method), the input parameters are new props and state, the returned value is a boolean, true means to continue rendering, false means to prevent rendering, and returns true by default.

     In Vue, by monitoring the changes of related attribute values, the mechanism automatically determines whether rendering is required, and cannot be "humanly" intervened. In Reactjs, using shouldComponentUpdate provides us with the opportunity to intervene and carry out precise control.

Applicable scenarios: When certain states or properties change, compare this.props and nextProps and this.state and nextState to determine whether the component needs to be re-rendered.

Function example: Let's write down SearchHot.js instead. When the number of hot searches changes, it returns false and does not continue rendering.

shouldComponentUpdate(nextProps,nextState){
        console.log(nextState.hotItem.length);
        if(this.state.hotItem.length != nextState.hotItem.length){
            return false;
        }
        return true;
    }

Because the lengths of the old and new values ​​of state.hotItem are inconsistent, click "Next Batch" and the page will not change.

It should be noted that the state and props need to keep the structure simple, the level should not be too deep, and it is not recommended  shouldComponentUpdate() to make a deep comparison or use in it  JSON.stringify(). This greatly affects efficiency and can impair performance.

If you only do a shallow comparison, you can consider using React.PureComponent.

  • componentWillUpdate (nextProps, nextState) (Abandoned soon)

This hook function will be deprecated in React 17 version,

Call timing: When the component receives new props or state, it will be called before rendering.

The role of the hook : The input parameter is the new props and state. Use this as an opportunity to perform the preparation update before the update occurs. This method will not be called for initial rendering.

Applicable scenarios : You can read DOM attributes to prepare for componentDidUpdate (fewer use scenarios). Cannot be called in this method this.setState()

  • componentDidUpdate(prevProps, prevState, snapshot)

Call timing : Called after the component has been re-rendered, this method will not be executed for the first rendering.

The role of the hook: the input parameter is the previous props, state value, the third parameter is related to the new version getSnapshotBeforeUpdate, introduced in the next section. Its function is similar to componentDidMount. At this time, the mounting is completed and you can do DOM operation and network request.

Use scenario: Operate on the DOM, such as assigning the scroll bar to the position, obtaining the DOM size, etc. In this method, you can call setState, but it must be wrapped in a certain condition, otherwise it will cause an infinite loop. Calling setSate will cause another rendering, although the user cannot see it (the browser has not changed at this time), but it will affect performance.

Function example:    Let's write SearchList.js instead. Each time the update is completed, the scroll bar points to the specified position of the list. (Here, ref is used to get the dom object, which will be introduced later)

componentDidUpdate(prevProps, prevState, snapshot){
    console.log("componentDidUpdate");
     //列表的滚动条指向60的位置
     this.searchul.current.scrollTop=60;
  }
...
render(){
 ...
 <ul className="u" ref={this.searchul}>
...
}

3. Unmounting

This stage means that the component will be deleted and cleared from the DOM.

  • componentWillUnmount()

Call timing: Called directly before the component is unloaded and destroyed.

Applicable scenarios: Perform the necessary cleaning operations in this method, for example, to clear the timer and cancel the network request. Do not call setState in this method, because the component will never render.

Third, the new version

V16.3 version has enabled the new version of the life cycle hook function, but this version is also compatible with the old version of the hook function, just like the old version, there are also three scenarios.

The schematic diagram of the life cycle hook function timing is as follows:

Compared with the old version, the hook function sends the following changes:

删除:componentWillMount,componentWillReceiveProps,componentWillUpdate

Added: getDerivedStateFromProps, getSnapshotBeforeUpdate.

Other functions are reserved. We highlight the new additions.

  • static getDerivedStateFromProps(nextProps,preState)

Calling timing: After props and state send updates, they will be called before calling the render method. Compared with the old life cycle diagram, it can be seen that getDerivedStateFromProps is in the original componentWillMount and componentWillReceiveProps position, and the call of setState and forceUpdate methods will trigger the hook.

The role of the hook: As you can see from the function name of the hook, use the accepted props value to change the state value and return a new state. Its input parameters are new props and old state. The function is static, which means that the component instance cannot be used (this cannot be called).

Applicable scenarios: Components are divided into controlled and uncontrolled components. Controlled refers to the component whose data is passed in from the props of the parent component (can be controlled by the parent component). Uncontrolled refers to the component whose data is stored in the internal state It cannot be controlled directly from the outside). If state can be derived from props, then it means that the component is both controlled and uncontrolled. The data source is not unique and will cause some unexpected problems. Deriving state through props is a situation that we need to avoid as much as possible .

The official document also lists alternatives for the following two common scenarios for us , which are described in detail in this blog post where you may not need to use derived state .

(1) If you only want to recalculate some data when prop changes, please use memoization helper instead.
(2) If you want to "reset" certain states when the prop changes, please consider making the component completely controlled or using the key to make the component completely uncontrolled instead.

Function example: In the SearchList component, the search result list is passed to the component by the parent component App through props. Below we modify it, define a default list in the SearchList and save it to the state. When the parent component passes in the prop list result After the update, modify the state value to achieve the update.

constructor(props){
    super(props);
    this.searchul = React.createRef();
    //定义默认搜索列表
    this.state={searchListVal:['电脑','电视','冰箱']};
  }
  static getDerivedStateFromProps(nextProps,preState){
    //当props的列表发送更新,且与state的列表不一致,且不为空
     if(nextProps.searchListVal!=preState.searchListVal&&nextProps.searchListVal.length > 0){
      //修改state的searchListVal值,返回新值
       return{
        searchListVal:nextProps.searchListVal
       }
     }
     //其他更新,state不变化
     return null;
  }
  • getSnapshotBeforeUpdate(prevProps, prevState)

Call timing: Called before the last rendering output (committed to the DOM node).

The role of the hook: it allows your components to obtain them before the current value may change. Any value returned by this life cycle will be passed as a parameter to componentDidUpdate (), which is the snapshot input parameter.

Applicable scenarios: Applicable scenarios are also not commonly used. It may appear in UI processing, such as chat threads that need to handle scrolling positions in a special way.

Function example: In the SearchList component, we use componentDidUpdate to scroll the scroll bar to the specified position every time the list is loaded. Next, we modify it again to obtain the position before the scroll bar, and then accumulate a specified value on the basis of it. In the case of lazy loading, the latest loaded value is displayed each time (bottom of the list).

getSnapshotBeforeUpdate(prevProps, prevState){
    //获取当前滚动条位置
    return this.searchul.current.scrollTop;
  }
  componentDidUpdate(prevProps, prevState, snapshot){
    //在滚动条位置上,累加60个
    if(snapshot!=null){
      this.searchul.current.scrollTop=snapshot+60;
    } 
  }

Fourth, compared with Vue's life cycle

Here we compare the life cycle of Reactjs with Vue.

1. When mounting

2. When updating

3. When destroyed

V. Summary

This chapter mainly describes the old and new life cycle of Reactjs and the timing, function, and applicable scenarios of related hook functions, and compares it with the life cycle of vue.

The timing of the old version of the life cycle hook function:

1. When mounting, constructor-> componentWillMount-> render-> componentDidMount

2、更新时,componentWillReceiveProps->shouldComponentUpdate->componentWillUpdate->render->componentDidUpdate

3. When uninstalling, componentWillUnmount

The timing of the new version of the life cycle hook function:

1. When mounting, constructor-> getDerivedStateFromProps-> render-> componentDidMount

2、更新时,getDerivedStateFromProps->shouldComponentUpdate->render->componentDidUpdate

3. When uninstalling, componentWillUnmount

Published 33 original articles · Liked 95 · Visitors 30,000+

Guess you like

Origin blog.csdn.net/tcy83/article/details/104343082