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

Detailed explanation of the lock structure in MySQL

Mysql supports 3 types of lock structures Table-l...

Detailed explanation of selinux basic configuration tutorial in Linux

selinux ( Security-Enhanced Linux) is a Linux ker...

A brief analysis of MySQL explicit type conversion

CAST function In the previous article, we mention...

The most commonly used HTML escape sequence

In HTML, <, >, &, etc. have special mean...

How to use fdisk to partition disk in Linux

Commonly used commands for Linux partitions: fdis...

Tools to convert static websites into RSS

<br /> This article is translated from allwe...

How to use vue3 to build a material library

Table of contents Why do we need a material libra...

Detailed explanation of client configuration for vue3+electron12+dll development

Table of contents Modify the repository source st...

HTML page common style (recommended)

As shown below: XML/HTML CodeCopy content to clip...

WeChat applet learning wxs usage tutorial

What is wxs? wxs (WeiXin Script) is a scripting l...

The most detailed method to install docker on CentOS 8

Install Docker on CentOS 8 Official documentation...

How to install SVN server under Linux

1. Yum installation yum install subversion 2. Con...

Detailed introduction to JS basic concepts

Table of contents 1. Characteristics of JS 1.1 Mu...

Analysis of the process of building a LAN server based on http.server

I don’t know if you have ever encountered such a ...