useMemo/useCallback/React.memo

返回一个 memoized 值

// useMemo返回一个值(可以是函数)
const computeExpensiveValue = (a, b) => {
    return a + b;
}
const memoizedValue = useMemo(computeExpensiveValue(a, b), [a, b]);


// useCallbak返回一个函数
const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);
  • useMemo和useCallback解决的因函数更新而渲染自己的问题
  • 它仅会在某个依赖项改变时才重新计算 memoized 值
  • 传入 useMemo 的函数会在渲染期间执行
  • 副作用属于 useEffect 的适用范畴,而不是 useMemo
  • 如果没有提供依赖项数组,useMemo 在每次渲染时都会计算新的值
  • useCallback(fn, deps) 相当于 useMemo(() => fn, deps)

与React.memo的区别

  • react.memo解决的是因父组件state变化因为的自组件重复刷新的问题
  • React.memo的用法
function MyComponent(props) {
  
}
function areEqual(prevProps, nextProps) {
  // 手动判断是否需要重新渲染
  // return true不渲染,false则渲染
}
export default React.memo(MyComponent, areEqual);

问题

  1. React.memo 第二个参数不用的话默认就 props 浅比较
  2. React.memo 在跟某些hooks配合使用的情况下会失效,例如在组件内部使用 useStateuseReduceruseContext ,当 state 或者 context 改变时,组件还是会重新渲染
import React, { useState } from "react";
function Child1(props) {
  console.log("执行子组件1了");
  return 
子组件1上的n:{props.value}
; } function Child2(props) { console.log("执行子组件2了"); return
子组件2上的m:{props.value}
; } const MChild1 = React.memo(Child1, () => { return false; // 失效 }); // compare失效会直接导致整个React.memo失效 const MChild2 = React.memo(Child2); export default function App() { const [n, setN] = useState(0); const [m, setM] = useState(10); console.log("执行最外层盒子了"); // 这里与是否是箭头函数无关 function addM() { setM(m + 1); } // 只要是复杂类型,都会渲染 const test = { a: 134 }; // 如果test是简单类型,则不会重复渲染 return ( <>
最外层盒子
); }

问题

  1. 自定义的compare函数失效,导致整个React.memo失效
  2. App重新执行了,它会修改复杂数据类型的地址,从而引发重新渲染
  • useMemo解决addN和addM地址变更引发的重复渲染的问题
import React, { useState, useMemo, useCallback, memo } from "react";
const Child1 = memo((props) => {
  console.log("执行子组件1了");
  return 
子组件1上的n:{props.value}
; }) const Child2 = memo((props) => { console.log("执行子组件2了"); return
子组件2上的m:{props.value.m}
; }) export default function App() { const [n, setN] = useState(0); const [m, setM] = useState({ m: 1 }); console.log("执行最外层盒子了"); const addN = useMemo(() => { return () => { setN(n + 1); }; }, [n]); const addM = useCallback(() => { setM({ m: m.m + 1 }); }, [m]); return ( <>
最外层盒子
); }

你可能感兴趣的:(useMemo/useCallback/React.memo)