91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

React中memo、useCallback和useMemo的使用場景是什么

發布時間:2023-03-06 17:43:26 來源:億速云 閱讀:118 作者:iii 欄目:開發技術

這篇“React中memo、useCallback和useMemo的使用場景是什么”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“React中memo、useCallback和useMemo的使用場景是什么”文章吧。

memo()、useCallback()、useMemo()使用場景

當父組件的props或state變化時,render重新渲染,但傳遞給子組件的props沒有發生變化說著只是簡單調用了一下子組件,這時子組件也要重新渲染,這就導致了組件的不必要的渲染

React.memo()

當父組件只是簡單調用子組件,并未給子組件傳遞任何屬性,我們可以通過memo來控制函數組件的渲染

React.memo()將組件作為函數(memo)的參數,函數的返回值(Child)是一個新的組件。

import { useState } from "react";
import { Child } from "./child";
export const Parent = () => {
  const [count, setCount] = useState(0);
  const increment = () => setCount(count + 1);
  return (
    <div>
      <button onClick={increment}>點擊次數:{count}</button>
      <Child />
    </div>
  );
};
import {memo} from 'react'
export const Child=memo(()=>{
    consloe.log('渲染了')
    return <div>子組件</div>
})
//使用memo()包裹后的組件,在Parent組件重新渲染更新時,Child組件并沒有重新渲染更新

當我們傳值給子組件時,這時使用memo函數就對控制組件的更新不起作用了

父組件

import { useState } from "react";
import { Child } from "./child";
export const Parent = () => {
  const [count, setCount] = useState(0);
  const [name, setName] = useState("小明");
  const increment = () => setCount(count + 1);
  const onClick = (name: string) => {
    setName(name);
  };
  return (
    <div>
      <button onClick={increment}>點擊次數:{count}</button>
      <Child name={name} onClick={onClick} />
    </div>
  );
};

子組件

import { memo } from "react";
export const Child = memo(
  (props: { name: string; onClick: (value: any) => void }) => {
    const { name, onClick } = props;
    console.log("渲染了", name, onClick);
    return (
      <>
        <div>子組件</div>
        <button onClick={() => onClick("小紅")}>改變 name 值</button>
      </>
    );
  }
);

出現這樣結果的原因:

點擊父組件按鈕時,改變了父組件的count,導致父組件重新渲染

父組件重新渲染時,重新創建了onClick函數,導致傳遞給子組件的onClick屬性發生了變化,導致子組件重新渲染

如果傳遞給子組件的只有基本數據類型將不會重新渲染

注意: 如果直接使用useState解構的setName傳給子組件, 子組件將不會重復渲染,因為解構出來的是一個memoized 函數。

React.useCallback()

所以,在這種情況下我們使用React.useCallback() useCallback(fn, deps)

import { useCallback, useState } from "react";
import { Child } from "./child";
export const Parent = () => {
  const [count, setCount] = useState(0);
  const [name, setName] = useState("小明");
  const increment = () => setCount(count + 1);
//使用useCallback鉤子包裹的回調函數是memoized函數,他初次調用該函數時,緩存參數和計算結果,再次調用這個函數時,如果第二個參數依賴項沒有發生改變,則直接返回緩存結果,不會重新渲染
  const onClick = useCallback((name: string) => {
    setName(name);
  }, []);
  return (
    <div>
      <button onClick={increment}>點擊次數:{count}</button>
      <Child name={name} onClick={onClick} />
    </div>
  );
};

但當我們傳遞的屬性name不字符串,而是對象時

父組件

import { useCallback, useState } from "react";
import { Child } from "./child";
export const Parent = () => {
  const [count, setCount] = useState(0);
  // const [userInfo, setUserInfo] = useState({ name: "小明", age: 18 });
  const increment = () => setCount(count + 1);
  const userInfo = { name: "小明", age: 18 };
  return (
    <div>
      <button onClick={increment}>點擊次數:{count}</button>
      <Child userInfo={userInfo} />
    </div>
  );
};

子組件

import { memo } from "react";
export const Child = memo(
  (props: { userInfo: { name: string; age: number } }) => {
    const { userInfo } = props;
    console.log("渲染了", userInfo);
    return (
      <>
        <div>名字: {userInfo.name}</div>
        <div>年齡:{userInfo.age}</div>
      </>
    );
  }
);

點擊父組件count,看到子組件每次都重新渲染了。 分析原因跟調用函數是一樣的:

  • 點擊父組件按鈕,觸發父組件重新渲染;

  • 父組件渲染,const userInfo = { name: "小明", age: 18 }; 一行會重新生成一個新對象,導致傳遞給子組件的 userInfo 屬性值變化,進而導致子組件重新渲染。

  • 注意: 如果使用useState解構的userInfo, 子組件將不會重復渲染,因為解構出來的是一個memoized 值。

這時我們使用 React.useMemo() useMemo(() => fn, dep)

React.useMemo()

useMemo()返回的是一個 memoized 值。

如果沒有提供依賴項數組,useMemo 在每次渲染時都會計算新的值。

import { useMemo, useState } from "react";
import { Child } from "./child";
export const Parent = () => {
  const [count, setCount] = useState(0);
  // const [userInfo, setUserInfo] = useState({ name: "小明", age: 18 });
  const increment = () => setCount(count + 1);
  const userInfo = useMemo(() => ({ name: "小明", age: 18 }), []);
  return (
    <div>
      <button onClick={increment}>點擊次數:{count}</button>
      <Child userInfo={userInfo} />
    </div>
  );
};

對比useCallback() 和useMemo()

useCallback(fn, deps) 返回該回調函數的memoized回調函數

const onClick = useCallback((name: string) => {
   setName(name);
 }, []);

useMemo(() => fn, dep) 返回的是一個 memoized 值。

const userInfo = useMemo(() => ({ name: "小明", age: 18 }), []);

以上就是關于“React中memo、useCallback和useMemo的使用場景是什么”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

论坛| 准格尔旗| 周口市| 兴安县| 平定县| 灵寿县| 泽州县| 赫章县| 枝江市| 乌鲁木齐县| 长治市| 吉木乃县| 那坡县| 永济市| 开封市| 肃南| 镇原县| 利辛县| 红原县| 泸水县| 札达县| 晋州市| 扎赉特旗| 溧水县| 龙山县| 贵港市| 广安市| 崇仁县| 宜黄县| 霸州市| 前郭尔| 开江县| 临武县| 洪泽县| 连山| 平顶山市| 石门县| 海原县| 光泽县| 米林县| 达拉特旗|