美文网首页
React Performance Hooks之useMemo

React Performance Hooks之useMemo

作者: 米诺zuo | 来源:发表于2023-10-30 14:19 被阅读0次

默认情况下,React 每次重新渲染时都会重新运行组件的整个主体。
优化重新渲染性能的常见方法是跳过不必要的工作。 例如,可以告诉 React 重用缓存的计算,或者如果数据自上次渲染以来没有更改,则跳过重新渲染。

要跳过计算和不必要的重新渲染,请使用以下 Hooks 之一:

  • useMemo 缓存计算结果。
  • useCallback缓存函数定义,再传递给优化组件。
    要优先考虑渲染,请使用以下 Hooks 之一:
  • useTransition 将状态转换标记为非阻塞并允许其他更新中断它。
  • useDeferredValue 可以推迟更新 UI 的非关键部分,并让其他部分先更新。

useMemo

useMemo 会在重新渲染之间缓存calculateValue结果,直到dependencies发生变化,第二个参数不传的话,会每次都调用计算函数。

const cachedValue = useMemo(calculateValue, dependencies)

定义

参数

  • calculateValue: 不带任何参数,例如 () =>,并返回想要计算的值。dependencies如果改变,会重新调用该函数。

  • dependencies: 依赖项列表,包括组件中计算中使用的每个值。例如:[todos, tab](通过 Object.is比较dependencies两次的值。

返回值

在初始渲染中,“useMemo”返回不带参数调用“calculateValue”的结果。

在下一次渲染期间,它将返回上次渲染中已存储的值(如果依赖项未更改),或者再次调用“calculateValue”,并返回“calculateValue”返回的结果。

用法

1.跳过重新计算

1.当 List 的 props 与上次渲染时相同时,可以通过将其包装在 memo:
中来告诉 List 跳过重新渲染:

import { useMemo, useState } from "react";

export function MemoDemo() {
  const [name, setName] = useState("Tom");
  const [todoList, setTodoList] = useState(["1", "2", "3"]);
  const todoData: any = useMemo(() => {
    return todoList.filter((item) => item != "1");
  }, [todoList]);

  return (
    <div>
      <div
        onClick={() => {
          setName("Lisa"); //click的时候, 不会在调用filter方法
        }}
      >
        memo {name}
      </div>
      <List todoList={todoData}></List>
    </div>
  );
}
function List({ todoList }) {
  return todoList.map((item) => <span key="item">{item}</span>);
}

2.记住另一个hook的依赖项

function Dropdown({ allItems, text }) {
  const searchOptions = { matchMode: 'whole-word', text };

  const visibleItems = useMemo(() => {
    return searchItems(allItems, searchOptions);
  }, [allItems, searchOptions]); // 🚩 注意: dependency是在组件中创建的object
  // ...

上述dependency是在组件中创建的object,每次组件在渲染的时候都会重新创建一个searchOption对象,每次都是不同的searchOptions对象, 所以visibleItems每次渲染都会执行。

如何解决这个问题?可以将searchOptions对象也通过useMemo存储下。

function Dropdown({ allItems, text }) {
  const searchOptions = useMemo(() => {
    return { matchMode: 'whole-word', text };
  }, [text]); // ✅ Only changes when text changes

  const visibleItems = useMemo(() => {
    return searchItems(allItems, searchOptions);
  }, [allItems, searchOptions]); // ✅ Only changes when allItems or searchOptions changes
  // ...

进一步的优化,可以将searchOptions对象放在useMemo计算方法内

function Dropdown({ allItems, text }) {
  const visibleItems = useMemo(() => {
    const searchOptions = { matchMode: 'whole-word', text };
    return searchItems(allItems, searchOptions);
  }, [allItems, text]); // ✅ Only changes when allItems or text changes
  // ...

3.缓存一个方法

export default function ProductPage({ productId, referrer }) {
  function handleSubmit(orderDetails) {
    post('/product/' + productId + '/buy', {
      referrer,
      orderDetails
    });
  }

  return <Form onSubmit={handleSubmit} />;
}

注意:{}, (){}, ()=> {},这种声明在重新渲染时, 会创建一个新的函数,那么对于缓存来说,会认为是不同的方法。
如何优化?

export default function Page({ productId, referrer }) {
  const handleSubmit = useMemo(() => {
    return (orderDetails) => {
      post('/product/' + productId + '/buy', {
        referrer,
        orderDetails
      });
    };
  }, [productId, referrer]);

  return <Form onSubmit={handleSubmit} />;
}

这样看着有些繁琐,进一步优化,使用useCallback

export default function Page({ productId, referrer }) {
  const handleSubmit = useCallback((orderDetails) => {
    post('/product/' + productId + '/buy', {
      referrer,
      orderDetails
    });
  }, [productId, referrer]);

  return <Form onSubmit={handleSubmit} />;
}

参考更多 useCallback.

好了,那我们的useMemo到这里就结束了。

宝子们可以收藏评论交流哦

相关文章

  • react hooks 之 useMemo

    useMemo 接受两个参数,第一个参数是一个函数,返回值用于产生保存值。 第二个参数是一个数组,作为 dep 依...

  • react hooks of useMemo

    今天解决了一个试了好几次都没搞定的问题 场景: 有个集中管理生成路由的功能,此处需要鉴权。用户签权用的是uesEf...

  • [React Hooks] useMemo 学习

    官网文档:https://reactjs.org/docs/hooks-reference.html#usemem...

  • useMemo

    useMemo:根据名字翻译为"备忘录",他在react的hooks中发挥什么样的作用呢?先根据查找到的资料,发现...

  • React hooks中memo,usememo,useCall

    memomemo类似于PureCompoent 作用是优化组件性能,防止组件触发重渲染memo针对 一个组件的渲染...

  • React Hooks

    React Hooks Hooks其实就是有状态的函数式组件。 React Hooks让React的成本降低了很多...

  • Hooks - useMemo & useCallBack &

    useMemo & useCallBack 在 React 中,当父组件发生变化的时候,子组件会重新渲染一遍,但是...

  • react-hooks

    前置 学习面试视频 总结react hooks react-hooks react-hooks为函数组件提供了一些...

  • React Hooks

    前言 React Conf 2018 上 React 提出了关于 React Hooks 的提案,Hooks 作为...

  • 5分钟简单了解React-Hooks

    首先附上官网正文?:React Hooks Hooks are a new addition in React 1...

网友评论

      本文标题:React Performance Hooks之useMemo

      本文链接:https://www.haomeiwen.com/subject/xgpbidtx.html