• React UseMemo源码分析


    useMemo

    useMemo 是 React 提供的内置 Hooks,主要作用就是缓存,如果依赖项没有变化,Memo 方法不会再次执行,计算量比较高的方法可以使用,从而提高用户体验。本文将通过一个例子跟踪 Memo 的创建、更新流程。

    App.js

    //App.js
    import { useState } from 'react';
    import { createTodos } from './utils.js';
    import TodoList from './TodoList.js';
    
    const todos = createTodos();
    
    export default function App() {
      const [tab, setTab] = useState('all');
      const [isDark, setIsDark] = useState(false);
      return (
        <>
          
          
          
          

    ); }
    //TodoList.js
    import List from './List.js';
    import { filterTodos } from './utils.js'
    import {useMemo} from 'react'
    
    export default function TodoList({ todos, theme, tab }) {
      const visibleTodos = useMemo(
        () => filterTodos(todos, tab),
        [todos, tab]
      );
      return (
        

    Note: List is artificially slowed down!

    ); }
    
    /*
     *  filename List.js
     * 
     */
    import { memo } from 'react';
    
    const List = memo(function List({ items }) {
      console.log('[ARTIFICIALLY SLOW] Rendering  with ' + items.length + ' items');
      let startTime = performance.now();
      while (performance.now() - startTime < 500) {
        // Do nothing for 500 ms to emulate extremely slow code
      }
    
      return (
        
      {items.map(item => (
    • {item.completed ? {item.text} : item.text }
    • ))}
    ); }); export default List;
    /*
     *  filename utils.js
     * 
     */
    export function createTodos() {
        const todos = [];
        for (let i = 0; i < 50; i++) {
          todos.push({
            id: i,
            text: "Todo " + (i + 1),
            completed: Math.random() > 0.5
          });
        }
        return todos;
      }
      
      export function filterTodos(todos, tab) {
        return todos.filter(todo => {
          if (tab === 'all') {
            return true;
          } else if (tab === 'active') {
            return !todo.completed;
          } else if (tab === 'completed') {
            return todo.completed;
          }
        });
      }
      
    

    初始化

    首次进入,运行并绑定结果。
    在这里插入图片描述
    进入绑定逻辑,可以看到 nextCreate 在这里运行,返回结果和依赖项。
    在这里插入图片描述

    更新

    点击 active 按钮,进入memo 更新流程
    在这里插入图片描述
    如果依赖没有变化,直接返回,有变化运行函数并更新。
    在这里插入图片描述
    Memo 的值也是存在 FiberNode 的memoizedState 属性中

    在这里插入图片描述

    总结

    Memo 的原理是根据依赖项变化判断是否更新,数据存在 FiberNode 上进行集中控制,更新时从组件的 FiberNode 上获取上次记录的状态并与本次的状态进行比较,并根据比较结果进行相应的处理。

  • 相关阅读:
    Vue复刻华为官网 (一)
    jquery---动画
    PDCA循环——快速提升软件质量的必备工具
    HTML <th> 标签
    Excel使用笔记
    2023年【汽车驾驶员(高级)】考试试卷及汽车驾驶员(高级)理论考试
    linux挖矿病毒kthreaddk横行,如何灭掉它?
    MySQL 学习笔记(基础)
    唤起testFlight、唤起AppStore
    js 转成Number , Boolean类型
  • 原文地址:https://blog.csdn.net/hawk2014bj/article/details/139320452