赞
踩
useMemo 是 React 提供的内置 Hooks,主要作用就是缓存,如果依赖项没有变化,Memo 方法不会再次执行,计算量比较高的方法可以使用,从而提高用户体验。本文将通过一个例子跟踪 Memo 的创建、更新流程。
//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 ( <> <button onClick={() => setTab('all')}> All </button> <button onClick={() => setTab('active')}> Active </button> <button onClick={() => setTab('completed')}> Completed </button> <br /> <label> <input type="checkbox" checked={isDark} onChange={e => setIsDark(e.target.checked)} /> Dark mode </label> <hr /> <TodoList todos={todos} tab={tab} theme={isDark ? 'dark' : 'light'} /> </> ); }
//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 ( <div className={theme}> <p><b>Note: <code>List</code> is artificially slowed down!</b></p> <List items={visibleTodos} /> </div> ); }
/* * filename List.js * */ import { memo } from 'react'; const List = memo(function List({ items }) { console.log('[ARTIFICIALLY SLOW] Rendering <List /> with ' + items.length + ' items'); let startTime = performance.now(); while (performance.now() - startTime < 500) { // Do nothing for 500 ms to emulate extremely slow code } return ( <ul> {items.map(item => ( <li key={item.id}> {item.completed ? <s>{item.text}</s> : item.text } </li> ))} </ul> ); }); 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 上获取上次记录的状态并与本次的状态进行比较,并根据比较结果进行相应的处理。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。