• 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 上获取上次记录的状态并与本次的状态进行比较,并根据比较结果进行相应的处理。

  • 相关阅读:
    为什么需要线程池?什么是池化技术?
    容器内的Linux诊断工具0x.tools
    前端工作总结293-uni-增加添加成功提示
    qt源码解析1--事件循环原理(重写事件函数,事件过滤器等)
    打造更安全的视频加密,云点播版权保护实践
    fifa将采用半自动越位技术计算进球
    第7个1024
    ACM浅聊
    M1芯片使用android-emulator-m1-preview模拟器提示INSTALL_FAILED_INSUFFICIENT_STORAGE 解决办法
    golang学习笔记01——基本数据类型
  • 原文地址:https://blog.csdn.net/hawk2014bj/article/details/139320452