react 中 memo 模块作用

`memo`是一个用于优化组件性能的高阶组件。

一、避免不必要的重新渲染

1. 浅比较机制原理

1.1 组件渲染触发条件

在 React 中,当组件的`props`或`state`发生变化时,组件会重新渲染。然而,在某些情况下,即使父组件重新渲染并传递给子组件相同的`props`,子组件也不需要重新渲染。`memo`模块通过对组件的`props`进行浅比较来解决这个问题。浅比较会检查`props`对象的引用是否发生变化,如果`props`的引用没有改变,并且组件是一个纯函数组件(没有内部状态或副作用),那么`memo`会阻止子组件的重新渲染。

1.2 代码示例

javascript 复制代码
import { memo } from "react";



const MyComponent = memo((props) => {

  return <div>{props.value}</div>;

});



export default MyComponent;

2. 性能优化效果

2.1 提升应用性能

例如:在一个列表组件中,每个列表项都是一个子组件,如果列表项的内容没有变化,使用`memo`可以防止列表项组件在父组件重新渲染时重新渲染。

2.2 减少渲染成本

每次组件重新渲染都需要重新执行组件函数,生成新的虚拟 DOM,然后与旧的虚拟 DOM 进行比较,这个过程会消耗一定的计算资源。`memo`通过阻止不必要的重新渲染,减少了这些渲染成本,尤其是在组件树较深或组件更新频繁的场景中,效果更加明显。

二、与函数组件的协同作用

1. 保持函数组件的纯洁性

1.1 纯函数组件概念

纯函数组件是指没有副作用且对于相同的输入总是返回相同输出的组件。`memo`与纯函数组件配合得很好,因为它的浅比较机制基于纯函数组件的特性。当一个函数组件被`memo`包裹后,它更符合纯函数的定义,即只要`props`不变,组件的输出(渲染结果)就不会改变。

1.2 代码示例

javascript 复制代码
import { memo } from "react";



const PureFunctionComponent = memo((props) => {

  // 这里没有副作用,只是根据传入的props渲染内容

  return <div>{props.text}</div>;

});



export default PureFunctionComponent;

2. 处理函数组件的依赖关系

2.1 函数组件中的依赖管理

例如:如果一个组件依赖于一个外部的格式化函数,当这个函数作为`props`传递给被`memo`包裹的组件时,`memo`会检测到这个`props`的变化并正确处理组件的重新渲染。

2.2 代码示例

javascript 复制代码
import { memo } from "react";



const formatText = (text) => text.toUpperCase();



const FunctionComponentWithDependency = memo((props) => {

  const formattedText = formatText(props.text);

  return <div>{formattedText}</div>;

});



export default FunctionComponentWithDependency;

三、与 React 其他特性的结合

1. 与 React Context 的结合使用

1.1 优化 Context 的消费组件

例如:在一个主题切换的应用中,有一个通过 Context 提供的主题颜色数据,使用`memo`包裹的组件可以在主题颜色没有直接影响其`props`时避免重新渲染。

1.2 代码示例

javascript 复制代码
import { memo, useContext, createContext } from "react";



const ThemeContext = React.createContext();



const ThemedComponent = memo((props) => {

  const theme = useContext(ThemeContext);

  // 这里只使用了与props相关的逻辑,不受ThemeContext变化的直接影响

  return <div style={{ color: props.textColor }}>{props.text}</div>;

});



export default ThemedComponent;

2. 与 React Hooks 的结合使用

2.1 配合 Hooks 实现复杂功能

例如:在一个使用`useEffect`来获取数据的组件中,`memo`可以防止组件在数据获取逻辑没有改变且`props`不变的情况下重新渲染。

2.2 代码示例

javascript 复制代码
import { memo, useState, useEffect } from "react";



const DataFetchingComponent = memo((props) => {

  const [data, setData] = useState(null);

  useEffect(() => {

    // 模拟数据获取逻辑

    const fetchData = async () => {

      const result = await fetch(props.url);

      const jsonData = await result.json();

      setData(jsonData);

    };

    fetchData();

  }, [props.url]);

  return <div>{data ? data.toString() : "Loading..."}</div>;

});



export default DataFetchingComponent;
相关推荐
谁呛我名字1 小时前
大数据应用开发——数据可视化
javascript·vue.js·echarts
前端郭德纲1 小时前
浅谈React的虚拟DOM
前端·javascript·react.js
2401_879103682 小时前
24.11.10 css
前端·css
ComPDFKit3 小时前
使用 PDF API 合并 PDF 文件
前端·javascript·macos
谈谈叭4 小时前
Javascript中的深浅拷贝以及实现方法
开发语言·javascript·ecmascript
优雅永不过时·4 小时前
Three.js 原生 实现 react-three-fiber drei 的 磨砂反射的效果
前端·javascript·react.js·webgl·threejs·three
爱编程的鱼5 小时前
javascript用来干嘛的?赋予网站灵魂的语言
开发语言·javascript·ecmascript
神夜大侠6 小时前
VUE 实现公告无缝循环滚动
前端·javascript·vue.js
明辉光焱6 小时前
【Electron】Electron Forge如何支持Element plus?
前端·javascript·vue.js·electron·node.js