useMemo与useCallback

234 阅读1分钟

Hook API之useMemo与useCallback

useMemo

把“创建”函数和依赖项数组作为参数传⼊入 useMemo ,它仅会在某个依赖项改变时才重新计算 memoized 值。这种优化有助于避免在每次渲染时都进⾏行行⾼高开销的计算。

    import React, { useState, useMemo } from "react";
    export default function UseMemoPage(props) { 
     const [count, setCount] = useState(0); 
     const expensive = useMemo(() => {
       console.log("compute"); let sum = 0;
       for (let i = 0; i < count; i++) { 
         sum += i;
       }
       return sum;
      //只有count变化,这⾥里里才重新执⾏行行
     }, [count]);
    const [value, setValue] = useState(""); 
    return (
        <div>
            <h3>UseMemoPage</h3>
            <p>expensive:{expensive}</p>
            <p>{count}</p>
            <button onClick={() => setCount(count + 1)}>add</button>
            <input value={value} onChange={event => setValue(event.target.value)} />
        </div>
    );
    }

useCallback

内联回调函数及依赖项数组作为参数传⼊入 useCallback ,它将返回该回调函数的 memoized 版本, 该回调函数仅在某个依赖项改变时才会更更新。当你把回调函数传递给经过优化的并使⽤用引⽤用相等性去避 免⾮非必要渲染(例例如 shouldComponentUpdate )的⼦子组件时,它将⾮非常有⽤用。

    import React, { useState, useCallback, PureComponent } from "react";
    export default function UseCallbackPage(props) { 
     const [count, setCount] = useState(0);
     const addClick = useCallback(() => { 
       let sum = 0;
       for (let i = 0; i < count; i++) { 
         sum += i;
       }
        return sum;
     }, [count]);
    const [value, setValue] = useState(""); 
        return (
            <div>
             <h3>UseCallbackPage</h3>
             <p>{count}</p>
             <button onClick={() => setCount(count + 1)}>add</button>
             <input value={value} onChange={event => setValue(event.target.value)} />
             <Child addClick={addClick} />
            </div>
        );
    }
    class Child extends PureComponent { 
        render() {
         console.log("child render"); 
         const { addClick } = this.props; 
         return (
          <div>
          <h3>Child</h3>
          <button onClick={() => console.log(addClick())}>add</button>
         </div>
        );
    }

useCallback(fn,deps) 相当于useMome(()=>fn,deps) 注意 依赖项数组不不会作为参数传给“创建”函数。虽然从概念上来说它表现为:所有“创建”函数中引⽤用的值都应该出现在依赖项数组中。未来编译器器会更更加智能,届时⾃自动创建数组将成为可能。