React component lifecycle

In version 17.0.1, React has modified the life cycle of components. The new life cycle and the old life cycle have not changed much. The new life cycle has added two new hook functions, and three hook functions are outdated.  

1, Old life cycle

The life cycle of components can be divided into three stages: initialization stage, update stage and uninstall stage.

Initialization phase: trigger in sequence.

                 constructor() --->

                 componentWillMount() --->

                 render() --->

                 componentDidMount()

Update phase: there are three update methods. Different methods trigger functions down from different hook functions in turn.

(1) the first is the whole phase of the update phase, which is triggered by the parent component's re render.

Parent component render -- >

                        componentWillReceiveProps() --->

                        shouldComponentUpdate() --->

                        componentWillUpdate --->

                        render() --->

                        componentDidUpdate()

(2). The second method is triggered after modifying the state (execute setState()).

Execute setstate() --- >

                        shouldComponentUpdate() --->

                        componentWillUpdate --->

                        render() --->

                        componentDidUpdate()

(3). The third method is forced update. Execute forceUpdate().

Execute forceupdate() --- >

                        componentWillUpdate --->

                        render() --->

                        componentDidUpdate()

Unloading phase: by reactdom Unmountcomponentatnode() trigger

                componentWillUnmount()

Initialization phase

<script type="text/babel">
        // Create component
        class Sum extends React.Component{

            constructor(props) {
                console.log('constructor')
                super(props)
                // Initialization status
                this.state = {count: 0}
            }

            // Add button
            add = () => {
                // Get original status
                const {count} =this.state
                // Update status
                this.setState({count: count+1})
            }

            // Component will be mounted
            componentWillMount() {
                console.log('componentWillMount')
            }

            // Component mounting completed
            componentDidMount() {
                console.log('componentDidMount')
            }

            //Timing of render call: initialize rendering, after status update
            render() {
                console.log('render')
                const {count} = this.state
                return(
                    <div>
                        <h2>{count}</h2>
                        <button onClick={this.add}>+1</button>
                    </div>
                )
            }
        }
        ReactDOM.render(<Sum />, document.getElementById('test'))
    </script>

         

In the initialization stage, the commonly used hook function is componentDidMount(). After the component is mounted, for example, there is a timing function after the page is displayed.

When the page is just mounted, the number on the page will increase by 1 every second, and the timer will be written to componentDidMount():

<script type="text/babel">
        // Create component
        class Sum extends React.Component{

            state = {count:0}

            unmount = () => {
                // Uninstall components
                ReactDOM.unmountComponentAtNode(document.getElementById('test'))
            }

            // After the component is mounted, it is called only once
            componentDidMount() {
                // Set a timer and increase it every second
                this.timer = setInterval(()=>{
                    let {count} = this.state
                    count += 1
                    this.setState({count})
                },1000);
            }

            // When the component is about to be uninstalled
            componentWillUnmount() {
                // Clear timer
                clearInterval(this.timer)
            }

            //Timing of render call: initialize rendering, after status update
            render() {
                return(
                    <div>
                        <h2>{this.state.count}</h2>
                        <button onClick={this.unmount}>Uninstall components</button>
                    </div>
                )
            }
        }
        // Render component to page
        ReactDOM.render(<Sum/>, document.getElementById('test'))
    </script>

Update phase:

The first refers to the parent component. This method requires two components, a child component and a parent component.

First, create two components, component A and component B. the calculation results are carried out in component A, and then the calculated results are transmitted to component B. the transmission data is transmitted by props, and the calculation results are displayed in component B. Component a saves the results in the state state, and the update state must update render, so it constitutes the condition for the parent component to re render.

<script type="text/babel">
        //A component
        class Acomponent extends React.Component{
            state = {count: 0}
            add = () => {
                this.setState({count: this.state.count+1})
            }

            render() {
                return(
                    <div>
                        <div>A assembly</div>
                        <button onClick={this.add}>+1</button> 
                        <Bcomponent count={this.state.count}/>   
                    </div>
                )
            }
        }
        
        //B assembly
        class Bcomponent extends React.Component{
            componentWillReceiveProps() {
                console.log('componentWillReceiveProps')
            }

             // If the control component update is not written, there will be a default value of true
            // Write must have a return value
            shouldComponentUpdate() {
                console.log('shouldComponentUpdate')
                return true
            }

            // Component will be updated
            componentWillUpdate() {
                console.log('componentWillUpdate')
            }

            // Component update completed
            componentDidUpdate() {
                console.log('componentDidUpdate')
            }

            render() {
                console.log('render')
                return(
                    <div>B assembly{this.props.count}</div>
                )
            }
        }
        // Render component to page
        ReactDOM.render(<Acomponent />, document.getElementById('test'))
    </script>

 

Only the first update condition triggers the {componentWillReceiveProps() hook function.

shouldComponentUpdate() is a hook function that can control the update of components and return a Boolean value. If it returns true, it will continue to execute downward.

If the return is false, the component will not be updated and the subsequent hook function will not be executed.

If the hook function shouldComponentUpdate() is not written in the code, React will give a default value of true. If the hook function is written in the code, the return value must be written. If the return value is not written, an error will be reported.

The second method is to update the status, which reloads the components.

The following content is not much, so the code of modifying status update, forced update and uninstalling components is written in one code.

<script type="text/babel">
        // Create component
        class Sum extends React.Component{

            state = {count:0}

            // Callback of button
            add = () => {
                // Get original status
                const {count} =this.state
                // Update status
                this.setState({count: count+1})
            }

            // Uninstall components
            unmount = () => {
                ReactDOM.unmountComponentAtNode(document.getElementById('test'))
            }

            // Forced update
            force = () => {
                this.forceUpdate();
            }

            // Component will be uninstalled
            componentWillUnmount() {
                console.log('componentWillUnmount')
            }

            // If the control component update is not written, there will be a default value of true
            // Write must have a return value
            shouldComponentUpdate() {
                console.log('shouldComponentUpdate')
                return true
            }

            // Component will be updated
            componentWillUpdate() {
                console.log('componentWillUpdate')
            }

            // Component update completed
            componentDidUpdate() {
                console.log('componentDidUpdate')
            }

            //Timing of render call: initialize rendering, after status update
            render() {
                console.log('render')
                const {count} = this.state
                return(
                    <div>
                        <h2>{count}</h2>
                        <button onClick={this.add}>+1</button>
                        <button onClick={this.unmount}>Uninstall components</button>
                        <button onClick={this.force}>Force update without changing status</button>
                    </div>
                )
            }
        }
        // Render component to page
        ReactDOM.render(<Sum />, document.getElementById('test'))
    </script>

        

The first + 1 button is the button to update the status and save the displayed number in the status. It will be triggered in turn

 

You can control whether to update components by controlling the return value of {shouldComponentUpdate().

The third method is to force the update of components by calling the forceUpdate() function.

Because it is a forced update, it must be updated, so it is not controlled through shouldComponentUpdate().

In the process of writing code, you can update the status without updating the components, and you can force the components to be updated without updating the status. You can choose according to your own needs.

Unloading phase

In the unloading phase, there is only one hook function, and the componentWillUnmount() component will be unloaded by react Unmountcomponentatnode() triggers the unloading of components.

Some finishing work will be done at this stage. For example, in the previous example of timer, clear the timer in this hook function during unloading, otherwise an error will be reported.

2, New life cycle

Before understanding the new life cycle, we need to know why React needs to modify the life cycle. The content in the official website is as follows:

The above three life cycle methods are often misunderstood and abused. The React team needs to realize asynchronous rendering. In asynchronous rendering, their potential misuse problems may be greater, and there may be bug s in future versions of React.

That is to say, the React team is paving the way for the update of the later React version in advance to solve the possible problems in advance.

Two new lifecycles are introduced, static getDerivedStateFromProps and getSnapshotBeforeUpdate

getDerivedStateFromProps() emphasizes that it is static, so static should be added in front of it.

<script type="text/babel">
        // Create component
        class Count extends React.Component{

            state = {count: 0 }

            // Callback of button
            add = () => {
                // Get original status
                const {count} =this.state
                // Update status
                this.setState({count: count+1})
            }

            // Get a derived state from props
            // If the value of state depends on props at any time, you can use
            static getDerivedStateFromProps(props, state) {
                console.log('getDeriveStateFromProps', props, state)
                return null
                // return props
            }

            getSnapshotBeforeUpdate(prevProps, prevState) {
                console.log('getSnapshotBeforeUpdate', prevProps, prevState)
                return 'React'
            }

            // Component update completed
            componentDidUpdate(prevProps, prevState, snapshotValue) {
                console.log('componentDidUpdate', prevProps, prevState, snapshotValue)
            }

            //Timing of render call: initialize rendering, after status update
            render() {
                console.log('render')
                const {count} = this.state
                return(
                    <div>
                        <h2>{count}</h2>
                        <button onClick={this.add}>+1</button>
                        {/*<button onClick={this.death}>Uninstall components < / button >
                    <button onClick={this.force}>Force update without changing the status < / button >*/}
                    </div>
                )
            }
        }
        ReactDOM.render(<Count count={2}/>, document.getElementById('test'))
    </script>

It can return an object to update the state, or null to represent the new props, without any state update. If you don't use this function, it will increase the complexity of using the de bug state function very little.

Another new life cycle is getSnapshotBeforeUpdate. The return value of this life cycle will be passed to componentDidUpdate. Com as the third parameter

Figure is the running result of the above code.

The above two lines are triggered during component initialization and the following four lines are triggered during component update. getDerivedStateFromProps can get the props and state values of the current component, which are always the current values, while getSnapshotBeforeUpdate takes the previous values, which are the values when the component has not been updated.

When the component is updated, it is the updated component, and the information in the component before the update is gone. The information of the previous component can be returned by getSnapshotBeforeUpdate and passed to componentDidUpdate, which can store the information of the previous component. Everything can be stored, for example, keep the scroll position, component size data, etc. It is very useful in some cases.

summary

Whether it's an old life cycle or a new life cycle, there are three commonly used hook functions

componentDidMount(), initialization work;

componentDidUpdate(), update work;

componentWillUnmount(), to finish the work.

These three hook functions have not changed in the old life cycle or the new life cycle.

3, Using lifecycle hook functions in functional components

Hook is React16 New features and syntax added in version 8.0. state,refs and other React features (life cycle hook function) can be used in function components.

Effect Hook

Effect Hook allows you to perform side-effect operations in function components (used to simulate life cycle hooks in class components).

import React from "react"
import  ReactDOM  from "react-dom"

function Component() {

    const [count, setCount] = React.useState(0)

    function add() {
        setCount((count)=>{return count+1})
    }

    function unmount() {
        ReactDOM.unmountComponentAtNode(document.getElementById('root'))
    }
    

    //Equivalent to componentDidMount()
    // React.useEffect(()=>{
    //     console.log('initialization ')
    // }, [] / / nothing is added in parentheses. It is only called when the page is just mounted


    //Equivalent to componentDidUpdate()
    // React.useEffect(()=>{
    //     console.log('initialize and update ')
    // }, [count] / / add the status in parentheses and update it when the status changes


    //Equivalent to componentWillUnmount() 
    React.useEffect(()=>{
        console.log('initialization')
        return ()=>{
            console.log('Uninstall components')
        }
    },[])


    return (
        <div>
            <h2>{count}</h2>
            <button onClick={add}>+1</button>
            <button onClick={unmount}>uninstall</button>
        </div>
    )
}

export default Component

(1) Syntax and Description:

        useEffect(() => { 

/ / any operation with side effects can be performed here

return() = > {/ / execute before uninstalling the component

/ / do some finishing work here, such as clearing the timer / unsubscribing

          }

}, [stateValue] / / if [] is specified, the callback function will only be executed after the first render()

(2) You can think of useEffect Hook as a combination of the following three functions

        componentDidMount()

        componentDidUpdate()

        componentWillUnmount() 

Keywords: Javascript Front-end React

Added by atravotum on Mon, 21 Feb 2022 15:29:03 +0200