[Front-end knowledge] React foundation consolidation (forty-three) - Effect Hook

React foundation consolidation (forty-three) - Effect Hook

1. Basic use of Effect Hook

Effect Hook is used to complete some functions similar to the life cycle in class.

When using class components, whether it is rendering, network requests or manipulating DOM, its logic and code are mixed together. For example, we want to display the counter result on the label. In the class component, we implement it through the life cycle, as follows:

import React, {
    
     PureComponent } from "react";

export class App extends PureComponent {
    
    
  constructor() {
    
    
    super();

    this.state = {
    
    
      counter: 100,
    };
  }

  componentDidMount() {
    
    
    document.title = this.state.counter;
  }

  componentDidUpdate() {
    
    
    document.title = this.state.counter;
  }

  render() {
    
    
    const {
    
     counter } = this.state;
    return (
      <div>
        <h2>计数:{
    
    counter}</h2>
        <button onClick={
    
    (e) => this.setState({
    
     counter: counter + 1 })}>
          +1
        </button>
      </div>
    );
  }
}

export default App;

In function components, we can use useEffect to complete things other than rendering the interface, that is, completion 副作用的事情. This makes the code and logic look clearer and more concise:

import React, {
    
     memo, useEffect, useState } from "react";

export default memo(function App() {
    
    
  const [count, setCount] = useState(200);

  // 完成一些除渲染外,副作用的事情
  useEffect(() => {
    
    
    // 当前传入的回调函数会在组件被渲染完成后,自动执行
    // 网络请求/DOM操作/事件监听
    document.title = count;
  });

  return (
    <div>
      <h2>计数:{
    
    count}</h2>
      <button onClick={
    
    (e) => setCount(count + 1)}>+1</button>
    </div>
  );
});

As you can see, through the Hook of useEffect, you can tell react what operations to perform after rendering. After react executes the update DOM operation, it will call back the callback function we passed in useEffect. By default, this function will be called whether it is the first render or after each update.

2. Effect that needs to be cleared

In the class component, we usually componentDidMountset the listening event in and componentWillUnmountclear the listening event in; while in the function component using useEffect, we can use the return value (callback function) of useEffect to realize the clearing operation of event monitoring:

import React, {
    
     memo, useEffect, useState } from "react";

export default memo(function App_clear() {
    
    
  const [count, setCount] = useState(0);

  // 在执行完渲染后,执行副作用事件
  useEffect(() => {
    
    
    // 监听事件
    // const unsubscribe = store.subscribe(() => {});

    // function foo() {}
    // eventBus.on("test", foo);

    // 监听和取消放在一个地方,内聚性高
    console.log("假设监听unsubscribe、eventBus等事件");

    // // 返回值:回调函数 => 组件重新渲染或组件卸载时执行
    return () => {
    
    
      console.log("取消监听unsubscribe、eventBus等事件");
    };
  });

  return (
    <div>
      <button onClick={
    
    (e) => setCount(count + 1)}>+1({
    
    count})</button>
    </div>
  );
});

The function returned in useEffect is an optional clearing mechanism of effect, which can realize the logic of setting monitoring and canceling monitoring together to improve cohesion.

image-20230731214407030

Three, the use of multiple Effects

Suppose we perform the following three operations in useEffect:

  // 在执行完渲染后,执行副作用事件
  useEffect(() => {
    
    
    // 1.修改document的title

    // 2.对redux中数据变量的监听

    // 3.监听eventBus中的事件
  });

We will find that as the number of events increases, the logic in useEffect will gradually become more complex. At this time, we can split it into multiple effects and execute them sequentially, that is, react supports multiple useEffects:

  // 在执行完渲染后,执行副作用事件
  useEffect(() => {
    
    
    // 1.修改document的title
    console.log('1.修改document的title');
  });

  useEffect(() => {
    
    
    // 2.对redux中数据变量的监听
    console.log('2.对redux中数据变量的监听');
  });

  useEffect(() => {
    
    
    // 3.监听eventBus中的事件
    console.log('3.监听eventBus中的事件');
  });

When we trigger page rendering each time, we can see that three events are executed in sequence:

image-20230731215518004

4. The execution mechanism of Effect

We found that the monitoring operation will be performed every time the button is clicked. Assuming that the effect is a network request event, a request will be initiated after each update. Such frequent monitoring and requests are definitely not what we want. We can use the second parameter of useEffect to control its execution mechanism:

  // 在执行完渲染后,执行副作用事件
  useEffect(() => {
    
    
    // 1.修改document的title
    console.log("1.修改document的title");
  }, [count]);

  useEffect(() => {
    
    
    // 2.对redux中数据变量的监听
    console.log("2.对redux中数据变量的监听");
  }, []);

  useEffect(() => {
    
    
    // 3.监听eventBus中的事件
    console.log("3.监听eventBus中的事件");
  }, []);

When we pass in an empty array, it means that the side effect event does not depend on any content. At this time, it is consistent with the effect of componentDidMount. useEffect will only be executed when it is loaded for the first time:

image-20230731220520078

When we pass in event 1 [count], it means that the useEffect where event 1 is located depends on the count variable, and when the count variable changes, it will be executed. Therefore, when we click the button to modify the count value, only event 1 will be triggered again and again:

image-20230731220704060

Guess you like

Origin blog.csdn.net/weixin_42919342/article/details/132031601