繁体   English   中英

useCallback 与 useMemo 以及何时使用它们

[英]useCallback vs. useMemo and when to use them

useCallbackuseMemo之间的主要区别是什么? 什么时候使用 React Hooks 的useCallback

useMemo(() => (bar) => foo + bar, [foo]);

使用 useCallback 的等效代码:

useCallback((bar) => foo + bar, [foo]);

使用回调只是useMemo与函数一起使用的速记变体。

这就是它存在的原因:当您使用useMemo ,该值通常会在其依赖项之一发生变化时发生变化。 例如:

const fullName = useMemo(() => firstName + lastName, [firstName, lastName]);

如果firstNamelastName更改, fullName也会更改。 另一方面,函数本身通常不需要重新计算,它们的依赖关系大多是可能会改变的闭包值。

const getFullName = useCallback(() => firstName + lastName, [firstName, lastName]);

在这里,当firstNamelastName更改时,我们不需要具有不同主体的完全不同的函数,但我们确实需要具有相同函数的新实例,以便它在闭包中具有最新值(依赖项) . 所以 React 团队只是为了方便起见添加了它,因为它是一个常见的用例,而且() => () =>语法有点难看。

useMemouseCallback都使用一种叫做记忆化,你可以像钩子记起了想起来了。


区别:

useMemo将记住/记住您传递给它的函数返回的,直到依赖关系发生变化。

const num = 10
const result = useMemo(() => num + num, [num])
// result is now equal to 20

useCallback会记住/记住你传递给它的实际函数,直到依赖关系发生变化,这会给你一些称为引用相等的东西。

const num = 10
const result = useCallback(() => num + num, [num])
// result is now equal to () => num + num.
// result === result between renders.

参照平等:

() => {} === () => {} // This is false
const a = () => {}
a === a // This is true

它们都将一个函数和一个依赖项数组作为参数,如'useEffect'。 只有在其中一个依赖项值发生更改时,才会更改函数的返回值 - 否则将返回缓存的值。

请注意,传递一个空的依赖数组或根本没有数组将导致Hook在每次调用时返回一个memoized值。

两者之间的主要区别在于'useCallback'返回一个memoized回调,'useMemo'返回一个memoized值,该值是函数参数的结果。

如果你必须处理大量数据,'useMemo'是完美的Hook,因为它将在第一次渲染时完成一次工作,然后在每个其他渲染上返回一个缓存版本。

但是,'useCallback'的使用方式不同。 例如,经常重新渲染的父组件。 在父级内部,我们有一个带有函数prop的子组件。 在每次重新渲染时,Child将无用地重新执行其函数prop。 但是,如果将'useCallback'作为具有依赖关系数组的prop传递,它将解决该问题,因为该函数仅在依赖关系更改时才会执行。 然后每个其他重新渲染都将获得一个缓存函数。

import React, { useState, useMemo, useCallback } from "react";

const App = () => {
  // We create two states that will keep count of the number of time all hooks are called
  const [callbackCount, setCallbackCount] = useState(0);
  const [memoCount, setMemoCount] = useState(0);

  const memoFunction = () => {
    console.log(memoCount, "memo called");
    // Do something that will take a lot of processing ...
  };

  // Here if we give an empty array of dependencies, the callback function will return the old value of callbackCount
  // because useCallback will return its memoized version
  const callbackFunction = useCallback(() => {
    console.log(callbackCount, "callback called");
    // Do something with callbackCount ...
    return callbackCount;
  }, [callbackCount]);

  // We create the memo hook, when memoCount changes, the function will be executed again
  useMemo(memoFunction, [memoCount]);

  return (
    <>
      {/* This component will receive a function that will change when the dependency value changes */}
      <ChildComponent action={callbackFunction} />

      {/* Change the callback hook dependency to trigger a change in the child */}
      <button onClick={() => setCallbackCount(callbackCount + 1)}>
        Change callback count
      </button>

      {/* After creating useMemo, each change of memoCount will trigger the function passed to the hook,
    otherwise the memoized value will be returned */}
      <button onClick={() => setMemoCount(memoCount + 1)}>
        Change memo count
      </button>
    </>
  );
};

const ChildComponent = ({action}) => {
  const [value, setValue] = useState(0)

  useEffect(() => {
    let val = action()
    setValue(val)
  }, [action]) 

  return(
    <>
    Child : {value}
    </>
  )
}

现在,您已准备好使用React Hooks优化代码。 回顾一下:你不应该使用'useCallback'和'useMemo'来做所有事情。 'useMemo'应该用于大数据处理,而'useCallback'是一种向代码添加更多依赖的方法,以避免无用的渲染。

我们可以使用useCallbackuseCallback一个函数,这意味着这个函数只有在依赖数组中的任何依赖发生变化时才会被重新定义。

useMemo(() => computation(a, b), [a, b])是让我们记住昂贵计算的钩子。 给定相同的 [a, b] 依赖项,一旦记忆,钩子将返回记忆值而不调用计算(a,b)。

本文介绍了不同的 React Memoization 方法:React.memo、useMemo、useCallback,它们之间有什么不同并附有实际示例: https ://medium.com/geekculture/great-confusion-about-react-memoization-methods-react-memo -usememo-usecallback-a10ebdd3a316

useMemo 用于记忆值,React.memo 用于包装 React Function 组件以防止重新渲染。 useCallback 用于记忆函数。

useMemo有助于防止重新渲染,除非对函数的依赖项已更改,而useCallback有助于防止重新渲染,除非函数已更改。 即当一个函数作为参数传递给另一个函数时, useCallback将只允许在传递不同的函数后重新渲染。 这是一个资源的链接,可能有助于进一步解释

https://btholt.github.io/complete-intro-to-react-v5/hooks-in-depth

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM