“This is the fourth day of my participation in the Gwen Challenge.

preface

React provides a series of lifecycle hook functions for class components, Constructor, getDerivedStateFromProps, Render, componentDidMount, shouldComponentUpdate, getSnapshotBeforeUpdate, componentDi DUpdate, componentWillUnmount. However, you can’t use Hook functions in function components, so React Hook is used to simulate these Hook functions.

(1)

There is no constructor concept in functional components. Function components do not need constructors. Review the tasks that class components need to perform in constructor functions.

  • Called before any other statementsuper(props), otherwise,this.propsIs undefined;
  • By givingthis.stateAssign object to initialize internal state;
  • Bind the instance to the event handler, otherwise it cannot be used in the functionthis.

In the function component, the component props can be passed in as the parameter of the function. Using the function of ES6 destruct assignment, the parameter data of the component can be obtained and the default value can be set for the parameter data.

import React from 'react';
const Index = (props) =>{
  const {title = 'hellow React'} = props;
  return(
    <div>{title}</div>
  )
}
export default Index;
Copy the code

Initialize state with useState Hook const [state, setState] = useState(initialState), where initialState is the initial value of a state.

If the initial value of state requires a complex set of calculations, you can pass a function to useState.

import React, { useState } from 'react';
const HelloWorld = (props) =>{
  const {num} = props;
  const getAamout = (num) =>{
    return num + 1;
  }
  const [amount,serAmount] = useState(() =>{return getAamout(num)})
  return(
    <div>{amount}</div>
  )
}
export default HelloWorld;
Copy the code

The initial value of state is used when the component is mounted. To avoid calling getAamout again for the initial amount value when the component is updated, wrap the getAamout function in () =>{return getAamout(num)} and pass it to useState.

2. Simulate getDerivedStateFromProps

The getDerivedStateFromProps hook function is used to derive a new state from the props of the component, which is fully controlled by the props.

For example, to derive an amount state from num prop, store the previous value of num prop in a prevNum state variable for comparison.

import React, { useState } from 'react'; const HelloWorld = (props) =>{ const {num} = props; const [prevNum, setPrevNum] = useState(null); const [amount,serAmount] = useState(0); if (num ! == prevNum) { serAmount(num+1); setPrevNum(num); } return( <div>{amount}</div> ) } export default HelloWorld;Copy the code

When a component is updated, it executes if (num! PrevNum == prevNum), if num and prevNum are not equal, serAmount(num+1) updates the amount state, and setPrevNum(num) saves the current num prop to prevNum state.

React Hook getDerivedStateFromProps

3, simulation render

Render This is the body of the function component itself.

4. Simulate componentDidMount

Because the componentDidMount hook function is executed only once in the life of the component, to execute useEffect only once (only when the component is mounted), you can pass an empty array ([]) as a second argument to useEffect, The first argument takes a function, executes in the function, and executes in the componentDidMount hook function.

import React, {useState,useEffect } from 'react'; const HelloWorld = (props) =>{ const [amount,serAmount] = useState(0); UseEffect (() =>{console.log(' componentDidMount hook function ') console.log(amount)}, [] ) return( <div>{amount}</div> ) } export default HelloWorld;Copy the code

shouldComponentUpdate

ShouldComponentUpdate hook function shouldComponentUpdate hook function shouldComponentUpdate hook function shouldComponentUpdate hook function shouldComponentUpdate hook function shouldComponentUpdate hook function shouldComponentUpdate hook function shouldComponentUpdate hook function shouldComponentUpdate hook function shouldComponentUpdate hook function shouldComponentUpdate hook function shouldComponentUpdate hook function shouldComponentUpdate hook function shouldComponentUpdate hook function: This is a hook function used to optimize performance. There are three ways to implement the shouldComponentUpdate hook function in function components, as described below.

6.1 Use React. Memo simulation

The react. memo wraps a component to compare its props, and this component can only be a function component. This component is updated when its props change.

The react. memo only checks the changes in the props of the packaged component. The memo does not compare the state of the component. If the state of the component is changed, the component update cannot be prevented.

import React, { useEffect } from 'react'; const HelloWorld = React.memo((props) => { const { num } = props; UseEffect (() => {console.log(' update ')}) return (<div>{num}</div>)}) export default HelloWorld;Copy the code

The comparison of props is superficial. If you want to make a deep comparison, you can use a custom comparison function passed in the second argument to React. Memo. Compare the props before and after the function receives the change as an argument.

import React, {useEffect } from 'react'; const HelloWorld = React.memo((props) =>{ const {num} = props; UseEffect (() = > {the console. The log (' updated ')}) return (< div > {num} < / div >)}, (prevProps, NextProps) =>{// update return false // not update return true}) export default HelloWorld;Copy the code

If the comparison function returns true, it does not update, and if it returns false, it updates. This is the opposite of the shouldComponentUpdate hook.

6.2 Simulation with useMemo

useMemo(() => fn, deps)
Copy the code

The first argument to useMemo is a function. The second argument is an array containing the data to listen for. When the data changes, the first argument is reexecuted. In addition, useMemo returns the value of the first argument.

If you return a component in the first argument function, the update of that component is controlled by the data in the second argument array, which indirectly implements the shouldComponentUpdate hook function.

But because you can’t use useState to define the state of a component in useMemo, you can only compare props to determine whether to update the component.

import React from 'react';
const HelloWorld = (props) =>{
  const {num} = props;
  return (
    <div>{num}</div>
  )
}
export default HelloWorld;
Copy the code
import React,{useMemo,useState} from 'react';
import HelloWorld from './HelloWorld';
const Index = (props) =>{
  const [num,setNum] = useState(1)
  const Hello = useMemo(()=>{
    return (
      <HelloWorld num={num}></HelloWorld>
    )
  },[num])

  return (
    <div>
      {Hello}
    </div>
  )
}
export default Index;
Copy the code

The HelloWorld component above will only be updated if num’s prop changes.

When using useMemo to wrap a component, the props of the component must be added to the array as the second parameter. Otherwise, when the props is updated, the props of the component is still old.

6.3 Use the useCallback to simulate

The difference between useCallback and useMemo is. UseCallback returns a function, useMemo returns a value.

The first argument to useCallback is a function that useCallback returns. The second argument is an array of the data to listen for, and the first argument is returned when the data changes.

If the first argument function is a function component, the update of that component is controlled by the data in the second argument array, which indirectly implements the shouldComponentUpdate hook function.

import React from 'react';
const HelloWorld = (props) =>{
  const {num} = props;
  return (
    <div>{num}</div>
  )
}
export default HelloWorld;
Copy the code
import React,{useCallback,useState} from 'react';
import HelloWorld from './HelloWorld';
const Index = (props) =>{
  const [num,setNum] = useState(1)
  const Hello = useCallback(()=>{
    return (
      <HelloWorld num={num}></HelloWorld>
    )
  },[num])

  return (
    <div>
      {Hello()}
    </div>
  )
}
export default Index;
Copy the code

The HelloWorld component is handled with useMemo and useCallback respectively, returning Hello. The only difference with useCallback is that {Hello()} uses the HelloWorld component like this.

UseCallback (fn, deps) is equivalent to useMemo(() => FN, deps).

When wrapping a component with useCallback, the props that are useful in the component must be added to the array as the second parameter. Otherwise, when the props is updated, the props in the component is still old.

7. Simulate getSnapshotBeforeUpdate

There is currently no Hook equivalent for the getSnapshotBeforeUpdate Hook function, but it will be added soon.

Analog componentDidUpdate

The first argument to useEffect takes a function, and the second argument is an array to which props or state are added to listen. The first argument to useEffect is executed when the props or state of the listener changes. You can put the code to be executed in componentDidUpdate hook function in useEffect’s first argument function.

import React,{useState} from 'react'; const HelloWorld = (props) =>{ const [num,setNum]=useState(1); const changNum = () =>{ setNum(2); } useEffect(() =>{console.log('num data changed ')},[num]) return (<div onClick={changNum}>{num}</div>)} export default HelloWorld;Copy the code

9, simulate componentWillUnmount

In the first argument function of useEffect, you can return a function that is executed when the component is unloaded. So you can simulate the componentWillUnmount hook function by putting the code to be executed in the function returned by the first argument function of useEffect.

import React,{useState} from 'react'; const HelloWorld = (props) =>{ const [num,setNum]=useState(1); UseEffect (() =>{const timer = setInterval (() =>{console.log(' timer ')},3000) return () =>{clearInterval(timer); useEffect() =>{const timer = setInterval (() =>{console.log(' timer ')},3000) return () =>{clearInterval(timer); },[]) return (<div>{num}</div>)} export default HelloWorld;Copy the code