React useMemo and useCallback usage scenarios

React useMemo and useCallback usage scenarios

useMemo

We know that when a parent component is re-rendered, all of its (state, local variables, etc.) are new. Once a child component depends on an object variable of a parent component, the child component will get a new object regardless of whether the object changes, which will invalidate the diff corresponding to the child component and re-execute the logic. In the following example, our side-effect dependency contains the object parameter passed in by the parent component, and a data request is triggered every time the parent component is updated.

function Info({
  style,
}) {
  console.log('Info rendering occurs');

  useEffect(() => {
    console.log('Reload data'); // Data will be reloaded every time a re-render occurs}, [style]);

  return (
    <p style={style}>
      This is the text in Info</p>
  );
}

function Page() {
  console.log('Page rendering');

  const [count, setCount] = useState(0);
  const style = { color: 'red' };

  // When the counter is +1, the Page is re-rendered, which in turn triggers the re-rendering of the Info return (
    <div>
      <h4>Count value: {count}</h4>
      <button onClick={() => setCount(count + 1)}> +1 </button>
      <Info style={style} />
    </div>
  );
}

React Hooks provides us with a solution. useMemo allows us to cache the passed in objects and recalculate and update the corresponding objects only when the dependencies change.

function Page() {
  console.log('Page rendering');

  const [color] = useState('red');
  const [count, setCount] = useState(0);
  const style = useMemo(() => ({ color }), [color]); // style will only change if color changes substantially // When the counter is +1, it triggers a re-rendering of the Page, which in turn triggers a re-rendering of the Info // However, since the style is cached, it will not trigger a reload of the data in the Info return (
    <div>
      <h4>Count value: {count}</h4>
      <button onClick={() => setCount(count + 1)}> +1 </button>
      <Info style={style} />
    </div>
  );
}

useCallback

React Hooks brings two changes to the data flow: first, it supports more friendly use of context for state management, avoiding the transfer of irrelevant parameters to the middle layer when there are too many layers; second, it allows functions to participate in the data flow, avoiding the transfer of redundant parameters to lower-level components.

As one of the core modules of hooks, useContext can obtain the current value of the passed context to achieve cross-layer communication. React's official website has a detailed introduction. What needs to be paid attention to is that once the context value changes, all components using the context will be re-rendered. In order to avoid redrawing irrelevant components, we need to construct the context reasonably. For example, starting from the new thinking mode mentioned in the first section, we can organize the context according to the relevance of the state and store related states in the same context.

In the past, if the parent and child components used the same data request method getData, and this method depended on the query value passed in from the upper layer, it was usually necessary to pass the query and getData methods together to the child component. The child component decided whether to re-execute getData by judging the query value.

class Parent extends React.Component {
   state = {
    query: 'keyword',
  }

  getData() {
    const url = `https://mocks.alibaba-inc.com/mock/fO87jdfKqX/demo/queryData.json?query=${this.state.query}`;
    // Request data...
    console.log(`Request path: ${url}`);
  }

  render() {
    return (
      // Passing a query value that a child component does not render <Child getData={this.getData} query={this.state.query} />
    );
  }
}

class Child extends React.Component {
  componentDidMount() {
    this.props.getData();
  }

  componentDidUpdate(prevProps) {
    // if (prevProps.getData !== this.props.getData) { // This condition is always true
    // this.props.getData();
    // }
    if (prevProps.query !== this.props.query) { // Can only use the query value to make judgments this.props.getData();
    }
  }

  render() {
    return (
      // ...
    );
  }
}

In React Hooks, useCallback allows us to cache a function and update it only when its dependencies change. This allows us to use useEffect in child components to achieve on-demand loading. With the cooperation of hooks, a function is no longer just a method, but can participate in the data flow of the application as a value.

function Parent() {
  const [count, setCount] = useState(0);
  const [query, setQuery] = useState('keyword');

  const getData = useCallback(() => {
    const url = `https://mocks.alibaba-inc.com/mock/fO87jdfKqX/demo/queryData.json?query=${query}`;
    // Request data...
    console.log(`Request path: ${url}`);
  }, [query]); // getData is updated only when query changes // Changes in count value will not cause Child to re-request data return (
    <>
      <h4>Count value: {count}</h4>
      <button onClick={() => setCount(count + 1)}> +1 </button>
      <input onChange={(e) => {setQuery(e.target.value)}} />
      <Child getData={getData} />
    </>
  );
}

function Child({
  getData
}) {
  useEffect(() => {
    getData();
  }, [getData]); // Functions can participate in the data flow as dependencies return (
    // ...
  );
}

The above is the detailed content of the usage scenarios of React useMemo and useCallback. For more information about the use of React useMemo and useCallback, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • Detailed explanation of using React.memo() to optimize the performance of function components
  • Remember a bug caused by React.memo

<<:  Detailed explanation and summary of the URL for database connection

>>:  Docker large-scale project containerization transformation

Recommend

A brief discussion on Python's function knowledge

Table of contents Two major categories of functio...

HTML table markup tutorial (1): Creating a table

<br />This is a series of tutorials provided...

Summary of practical methods for JS beginners to process arrays

join() method: connects all elements in an array ...

React implements the sample code of Radio component

This article aims to use the clearest structure t...

HTML markup language - form

Click here to return to the 123WORDPRESS.COM HTML ...

Facebook's nearly perfect redesign of all Internet services

<br />Original source: http://www.a-xuan.cn/...

How to install MySQL via SSH on a CentOS VPS

Type yum install mysql-server Press Y to continue...

Introduction to HTML Chinese Character Encoding Standard

In HTML, you need to specify the encoding used by...

MySQL 5.7.11 zip installation and configuration method graphic tutorial

1. Download the MySQL 5.7.11 zip installation pac...

Detailed steps for installing Tomcat, MySQL and Redis with Docker

Table of contents Install Tomcat with Docker Use ...

Canonical enables Linux desktop apps with Flutter (recommended)

Google's goal with Flutter has always been to...

5 ways to migrate Docker containers to other servers

Migration is unavoidable in many cases. Hardware ...

How to use Docker to build a tomcat cluster using nginx (with pictures and text)

First, create a tomcat folder. To facilitate the ...

Practical tutorial on modifying MySQL character set

Preface: In MySQL, the system supports many chara...

MySQL 8.0.13 installation and configuration tutorial under CentOS7.3

1. Basic Environment 1. Operating system: CentOS ...