用还是不用useMemo,这是一个问题

React Hooks的useMemo到底有什么用

useMemo是React提供的一个用于优化性能的Hook,它的作用是用来缓存计算结果,避免重复计算。可以将一些昂贵的计算操作放到useMemo函数中,这样只有在依赖项发生变化时才会重新计算,从而提高应用程序的性能。

1-useMemo的语法

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

其中,第一个参数是一个函数,用于执行昂贵的计算操作,第二个参数是一个数组,包含了所有的依赖项。当依赖项发生变化时,useMemo函数会重新计算值,否则它会返回缓存的值。

2-useMemo函数缓存计算结果

import React, { useState, useMemo } from 'react';
function App() {
  const [count, setCount] = useState(0);
  const [factorial, setFactorial] = useState(1);
  const calculateFactorial = (number) => {
    let result = 1;
    for (let i = 1; i <= number; i++) {
      result *= i;
    }
    return result;
  };
  const memoizedFactorial = useMemo(() => calculateFactorial(count), [count]);
  const handleIncrement = () => {
    setCount(count + 1);
  };
  const handleCalculateFactorial = () => {
    setFactorial(memoizedFactorial);
  };
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={handleIncrement}>Increment</button>
      <p>Factorial: {factorial}</p>
      <button onClick={handleCalculateFactorial}>Calculate Factorial</button>
    </div>
  );
}
export default App;

在上面的代码中,我们定义了一个计算阶乘的函数calculateFactorial,它用于计算当前计数器的阶乘。然后,我们在useMemo函数中调用该函数,将计算结果缓存起来。每当计数器的值发生变化时,useMemo函数会重新计算阶乘,并将计算结果缓存起来。然后,我们在点击“Calculate Factorial”按钮时,将缓存的阶乘值设置为当前的阶乘值。这样就可以避免重复计算,提高应用程序的性能。

3-什么情况下用useMemo包裹整个组件

在某些特殊情况下,如果组件中所有的状态都是由父组件传递而来,并且这些状态的传递是非常频繁的,那么可以考虑将整个组件用useMemo包裹,以避免不必要的重渲染。

例如,如果父组件传递了一个非常庞大的对象作为 props,而这个对象的每个属性都会被组件使用,那么可以将整个组件用useMemo包裹,以避免在每次渲染时都重新计算该对象。

import React, { useMemo } from 'react';
function MyComponent({ data }) {
  const memoizedData = useMemo(() => data, [data]);
  return (
    <div>
      <p>Name: {memoizedData.name}</p>
      <p>Age: {memoizedData.age}</p>
      <p>Address: {memoizedData.address}</p>
    </div>
  );
}
export default useMemo(MyComponent);

在上面的代码中,我们将MyComponent组件用useMemo包裹,并将data作为依赖项传递给useMemo函数。这样,当data发生变化时,MyComponent组件才会重新渲染,否则它会保持不变。

总的来说,使用useMemo包裹整个组件是一种比较特殊的情况,需要谨慎使用。通常情况下,应该尽量将useMemo的作用范围限制在局部变量或者函数中,以便更好地优化组件的性能。

4-反面案例

当使用useMemo的时候,需要注意以下几点,否则可能会出现错误的使用方式:

4.1-使用useMemo来优化简单的计算操作

例如简单的加减乘除运算,这样会增加代码的复杂度,反而会降低性能。

import React, { useMemo } from 'react';
function App() {
  const a = 10;
  const b = 20;
  const memoizedSum = useMemo(() => a + b, [a, b]);
  return (
    <div>
      <p>Sum: {memoizedSum}</p>
    </div>
  );
}
export default App;

4.2-将useMemo用于副作用操作

例如修改DOM或者发送网络请求等操作,这些操作应该放在useEffect中进行。

import React, { useMemo } from 'react';
function App() {
  const memoizedMessage = useMemo(() => {
    const message = 'Hello world';
    document.title = message;
    return message;
  }, []);
  return (
    <div>
      <p>{memoizedMessage}</p>
    </div>
  );
}
export default App;

4.3-将整个组件用useMemo包裹

这样会导致组件的所有状态都被缓存,当任何一个状态改变时,整个组件都需要重新渲染,反而会降低性能。

import React, { useState, useMemo } from 'react';
function App() {
  const [count, setCount] = useState(0);
  const memoizedState = useMemo(() => {
    return { count, setCount };
  }, [count, setCount]);
  const handleIncrement = () => {
    memoizedState.setCount(memoizedState.count + 1);
  };
  return (
    <div>
      <p>Count: {memoizedState.count}</p>
      <button onClick={handleIncrement}>Increment</button>
    </div>
  );
}
export default useMemo(App);

4.4-混用useMemouseCallback

它们虽然都可以用于缓存计算结果,但是它们的作用不同,useMemo用于缓存值,useCallback用于缓存函数。

import React, { useState, useMemo, useCallback } from 'react';
function App() {
  const [count, setCount] = useState(0);
  const memoizedValue = useMemo(() => {
    return count * 2;
  }, [count]);
  const memoizedFunction = useCallback(() => {
    setCount(count + 1);
  }, [count]);
  return (
    <div>
      <p>Value: {memoizedValue}</p>
      <button onClick={memoizedFunction}>Increment</button>
    </div>
  );
}
export default App;

总的来说,需要遵循useMemo的使用规范,避免出现上述错误的使用方式,以确保代码的正确性和性能的优化。

原文链接:https://juejin.cn/post/7216942649067585593 作者:星辰_Stars

(0)
上一篇 2023年4月2日 上午10:21
下一篇 2023年4月2日 上午10:31

相关推荐

发表回复

登录后才能评论