useCallback(2)

2022-11-04  本文已影响0人  未路过

子组件是因为memo包裹,所以才当porps发生改变的时候渲染,如果没有memo包裹,无论props该不该变,父组件重新渲染,它都会重新渲染。
我们想让count发生改变的时候,increment还是返回之前的值。
因为count发生改变的时候,它会传进来一个新函数,我们使用的是新函数。

const increment = useCallback(() => {
    setCount(count + 1);
  }, [count]); 

我们想让count发生改变的时候,increment还是返回之前的值。
方法1:将count依赖删除掉,把第二个参数变成空数组。但是会出现闭包陷阱。

const increment = useCallback(() => {
    setCount(count + 1);
  }, []);

方法2:useRef,在组件多次渲染的时候,返回的是同一个值。

import React, { memo, useCallback, useRef, useState } from "react";
import Hello from "./components/Hello";
const HyIncrement = memo((props) => {
  console.log("HYincrment被渲染");
  const { increment } = props;
  const decrement = function () {
    console.log("decrement");
  };
  return (
    <div>
      <button onClick={increment}>increment+1</button>
      <Hello decrement={decrement}></Hello>
    </div>
  );
});

const App = memo(() => {
  const [count, setCount] = useState(0);
  const [randomNum, setRandomNum] = useState(0);
  const countRef = useRef();

  countRef.current = count;
  /* 第一次渲染的时候,创建了coungRef对象,赋值,第二次执行 const countRef = useRef();
的时候,拿到的还是上一次的countRef值,然后这次count变成1了,  countRef.current也就变成1了,countRef不管渲染多少次,它始终是同一个对象。但是伴随每次渲染里面的current值是不断改变的 */
  const increment = useCallback(() => {
    setCount(countRef.current + 1);
  }, []);

  /* 所以第一次foo捕获的时候,不要捕获count,直接捕获countRef */
  return (
    <div>
      <h2>{count}</h2>
      <button onClick={increment}>点我加1</button>
      <hr></hr>
      <HyIncrement increment={increment}></HyIncrement>
      <hr></hr>
      <h2>randomNum:{randomNum}</h2>
      <button onClick={(e) => setRandomNum(Math.random().toFixed(2))}>
        修改message
      </button>
    </div>
  );
});

export default App;

这个样子,无论是修改count还是radomNum,home组件都是不会被渲染的。
大概是

      const testObj = { name: "why", age: 18 };
      function foo() {
        const ref = testObj;
        function bar() {
          console.log(ref.name);
        }
        return bar;
      }

      const fn = foo();
      fn(); //why

      testObj.name = "new name";
      fn(); //new name
上一篇下一篇

猜你喜欢

热点阅读