useEffect (side effects) in React

Table of contents

useEffect (side effect) introduction

useEffect (side effect) call time of various writing methods

1. Writing method 1: When there are no dependencies

The parent component passes the value to the child component:

 2. Writing method 2: When there is a monitored value in the dependency

 3. Writing method 3: When the dependency is an empty array

4. Writing method 4: Clear side effect writing method (if the side effect is a timer, clear the timer, if it is not clear, there will be a memory leak)

5. Writing method five: when the dependency is a function

important point


useEffect (side effect) introduction

useEffect is used to make function components can also perform side effects . So what are side effects?

The side effects of a function are other effects of the function on the external environment other than the return value . For example, if every time we execute a function, the function will operate on a global variable, then the operation on the global variable is a side effect of this function. In the world of React, our side effects can be roughly divided into two categories, one is to call the browser's API , such as using addEventListener to add event listening functions, etc., and the other is to initiate a request to obtain server data , such as when the user When the component is mounted, asynchronously obtain user information, etc.

The official words of react:

If you are familiar with React class lifecycle functions, you can think of useEffect Hook as a combination of three functions: componentDidMount, componentDidUpdate and componentWillUnmount.

componentDidMount component mount
componentDidUpdate component update
componentWillUnmount component will be destroyed

grammar:

import {useEffect} from "react"
useEffect(() => {
  /** 执行逻辑 */
  }, dependencies)  //dependencies是一个数组,是可选的

//或者:
useEffect(effect?=>clean?, dependencies?)

 The first parameter effect of useEffect is the side effect function to be executed . It can be any user-defined function. In this function, the user can operate some browser APIs or interact with the external environment, network requests, etc. This function will Called after each rendering of the component. useEffect can have a return value, which returns a function, and the system calls it before the component is re-rendered to clear side effects (for example, if the side effect is a timer, the code to clear the timer can be written in the return). Its second parameter dependencies (dependencies) to limit the execution conditions of the side effect  

useEffect (side effect) call time of various writing methods

1. Writing method 1: When there are no dependencies

The component where useEffect is located must be called every time it renders (including the first time): any change in the component will be executed (eg: the state deconstructed by useState is changed, and the component will be re-rendered, and the parent component will pass the value of the property to the child component. useEffect in the component will execute)

  //没有依赖项
  useEffect(()=>{
    console.log('组件每次渲染时都要调用(页面每次刷新)');
  })

In the component life cycle, there is a life cycle function that will be called when the parent component of the life cycle passes new properties to the child component . UseEffect can be used as a replacement.

The component's own state change will call beforeupdate and updated , and useEffect can be used instead.

The parent component passes the value to the child component:

 2. Writing method 2: When there is a monitored value in the dependency

Determine whether to execute side effects according to whether the monitored variable in the dependency changes. If it changes, it will execute it, and if it does not change, it will not execute it .

    //依赖项中有值时
    //页面首次渲染和父组件给子组件传的属性值和子组件自身的值改变(依赖项改变才会打印)
    useEffect(() => {
        console.log('页面首次渲染和依赖项改变的时候才会打印');
    },[num,props.title])

 3. Writing method 3: When the dependency is an empty array

It is equivalent to the Vue life cycle function mounted , that is, after the page is rendered (mounted) for the first time, it will not be executed regardless of the change in the value of the component later, unless the component is destroyed and then remounted.

    useEffect(() => {
        console.log('页面首次渲染');
    },[])

4. Writing method 4: Clear side effect writing method (if the side effect is a timer, clear the timer, if it is not clear, there will be a memory leak)

    useEffect(() => {
        let timer = setInterval(()=>{
            console.log(66666);
        },1000)
        return ()=>{
            //当组件下一次渲染前,执行这个函数:清除副作用(计时器就是一种副作用)
            console.log('当组件下一次渲染前,执行这个函数:清除副作用');
            clearInterval(timer);
        }
    })//这里没写依赖项,所以页面中的值改变就会刷新,比如useState解构出的state改变

 Question: The side effect function will not have a cache, so why is the timer written in the side effect function useEffect, and the previous timer is not cleared after the page (component) is refreshed? Just have to write return to return a function to clear side effects (timer)

5. Writing method five: when the dependency is a function

    let fn = ()=>{
        console.log(11111111);
    }
    useEffect(() => {
        console.log('此组件渲染时,就会运行(包括首次渲染)');
        // 该组件渲染时(包括首次渲染),就会执行副作用
        let timer = setInterval(()=>{
            console.log(66666);
        },1000)
        return ()=>{
            //而当该组件下一次运行(渲染)时,才会执行清除副作用函数(第一次渲染不执行(组件首次渲染时),下一次渲染才执行)
            console.log('当组件下一次渲染前,执行这个函数:清除副作用');
            clearInterval(timer);
        }
    },[fn])

 

 Analysis: When the dependency fn function is running, the side effect function will run (first execute the function returned by the return of the side effect function, clear the timer generated by the last rendering, and then execute the side effect function and regenerate a timer), However, the function returned by return does not necessarily run, because the function returned by return must be executed when the component is rendered next time. Because although the fn function is executed, it does not cause the component to re-render, so the function returned by return will not be executed.

The disadvantage is: when the function component is refreshed, the function fn will be regenerated exactly the same, which is unnecessary and will occupy memory. Is there a technique that, when the component is refreshed, the function fn like fn is not regenerated, but the fn in the original memory is used, and there is no need to re-open the memory space to generate the function fn. So I used useCallback

important point

1.

    //这种没依赖项
    let [data,setData] = useState('');
    useEffect(()=>{
        //这里可以进行请求后台数据,但是不能通过setData()将请求回来的数据把页面刷新
        //会陷入死循环,页面一刷新 useEffect就会执行,就会请求后台数据,请求回来的数据又
        //通过setData()导致页面数据改变然后刷新,这样就会陷入死循环
        setData();
    })   

    //如果有依赖项的话,就不会陷入死循环

2. When the component is re-rendered, a copy of the non-hook-related data will be regenerated, for example,

    let [num,setNum] = useState(100);  //hook相关的数据
    let m = 100;            //普通的数据
    let arr = [100,200,900];//普通的引用数据
    let fm = ()=>{}         //普通的引用数据

 

 

Those hook components starting with use will not be regenerated when refreshed, and those ordinary data will be regenerated. If the dependencies are common reference data such as arr, fm, etc., when the component is refreshed, it will be regenerated, and the memory space will be re-opened for generation, so it will lead to the execution of side-effect functions, so the dependencies of general side-effect functions are given by the parent component. The properties passed by the subcomponent or the state value deconstructed by useState.

 

Guess you like

Origin blog.csdn.net/weixin_47075145/article/details/127868300