最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文詳解React渲染優(yōu)化之useImmer

 更新時(shí)間:2023年05月07日 09:01:17   作者:Ryun  
在React日常開發(fā)中,我們常常被重復(fù)渲染或無意義渲染所折磨,窮盡腦汁,做各種優(yōu)化:memo、useMemo、useCallback、immutable等,本文主要講述immutable的簡(jiǎn)約版Immer,感興趣的同學(xué)可以一起來學(xué)習(xí)

從一個(gè)例子開始

import { FC, useState, useEffect } from 'react';

const App: FC = () => {
  const [list, setList] = useState({ a: 1 });

  useEffect(() => {
    setList({ a: 1 });
  }, []);

  console.log('測(cè)試');

  return (
    <>
      <h1>Hello Web3 React {list.a}</h1>
    </>
  );
};

export default App;
  • 看控制臺(tái)輸出結(jié)果

  • 因?yàn)閘ist是引用對(duì)象,雖然內(nèi)部的值相同,但引用地址變化了,因此react認(rèn)為state發(fā)生了變化,因此觸發(fā)了渲染,這也聯(lián)想到如果我們傳遞props時(shí)為對(duì)象或數(shù)組時(shí),會(huì)造成我們非期望渲染的緣由,那我們?cè)撊绾谓鉀Q這個(gè)問題呢?
  • 在此之前,先介紹一個(gè)react渲染檢查工具 why-did-you-render

渲染檢查工具

why-did-you-render, 可以在開發(fā)時(shí),幫你檢測(cè)無意義的渲染

  • 安裝 yarn add @welldone-software/why-did-you-render -D
  • src下創(chuàng)建 wdyr.tsx
/// <reference types="@welldone-software/why-did-you-render" />
import React from 'react';

if (process.env.NODE_ENV === 'development') {
  // eslint-disable-next-line
  const whyDidYouRender = require('@welldone-software/why-did-you-render');
  whyDidYouRender(React, {
    onlyLogs: true,
    titleColor: 'green',
    diffNameColor: 'darkturquoise',
    trackHooks: true,
    trackAllPureComponents: true,
  });
}
  • 在入口文件 index.tsx 引入

  •  4.上面的例子,輸出結(jié)果,顯示無意義渲染

要解決這個(gè)問題,需要我們使用到Immer

Immer 與 UseImmer

  • 不可變數(shù)據(jù):不可變數(shù)據(jù)的特點(diǎn)就是產(chǎn)出地址不同的對(duì)象引用,同時(shí)盡可能保留沒必要更新的屬性或者子屬性,這樣在你的組件樹中如果有數(shù)據(jù)的其他屬性或者子熟悉的依賴存在的話,可以避免一些rerender
  • immutable:不改變?cè)瓟?shù)據(jù),將變化的部分與不變的部分組成一個(gè)新的數(shù)據(jù)對(duì)象**
  • Immer:簡(jiǎn)化了不可變數(shù)據(jù)結(jié)構(gòu)的處理,與immutable代碼簡(jiǎn)單,去掉樹的壓縮,使用proxy代理,組合新的樹
    • immer 可以在需要使用不可變數(shù)據(jù)結(jié)構(gòu)的任何上下文中使用,例如:React state、Redux等
    • 不可變的數(shù)據(jù)結(jié)構(gòu)允許(高效)的變化檢測(cè):如果對(duì)象的引用沒有改變,那么對(duì)象本身也沒有改變。此外,它使克隆對(duì)象相對(duì)便宜:數(shù)據(jù)樹的未更改部分不需要復(fù)制,并且在內(nèi)存中與相同狀態(tài)的舊版本共享

  • 利用 produce 函數(shù),它將我們要更改的 state 作為第一個(gè)參數(shù),對(duì)于第二個(gè)參數(shù),我們傳遞一個(gè)名為 recipe 的函數(shù),該函數(shù)傳遞一個(gè) draft 參數(shù),我們可以對(duì)其應(yīng)用直接的 mutations。一旦 recipe 執(zhí)行完成,這些 mutations 被記錄并用于產(chǎn)生下一個(gè)狀態(tài)。 produce 將負(fù)責(zé)所有必要的復(fù)制,并通過凍結(jié)數(shù)據(jù)來防止未來的意外修改

Immer是如何工作的?

  • 使用 Immer,您會(huì)將所有更改應(yīng)用到臨時(shí) draft,它是 currentState 的代理。一旦你完成了所有的 mutations,Immer 將根據(jù)對(duì) draft state 的 mutations 生成 nextState。這意味著您可以通過簡(jiǎn)單地修改數(shù)據(jù)來與數(shù)據(jù)交互,同時(shí)保留不可變數(shù)據(jù)的所有好處

  • 使用 Immer 就像擁有一個(gè)私人助理。助手拿一封信(當(dāng)前狀態(tài))并給您一份副本(草稿)以記錄更改。完成后,助手將接受您的草稿并為您生成真正不變的最終字母(下一個(gè)狀態(tài))

Immer優(yōu)點(diǎn)

  • 深度更新輕而易舉
  • 開箱即用的結(jié)構(gòu)共享
  • 開箱即用的對(duì)象凍結(jié)
  • 代碼簡(jiǎn)潔
  • 小巧:3KB gzip

使用

state + Immer

useImmer

  • 替代 state

  • 本文開始的例子使用 useImmer
import { FC, useEffect } from 'react';
import { useImmer } from '@hooks/useImmer';

const App: FC = () => {
  const [list, setList] = useImmer({ a: 1 });

  useEffect(() => {
    // setList({ a: 1 });
    setList(draft => {
      draft.a = 1;
    });
  }, []);

  console.log('測(cè)試');

  return (
    <>
      <h1>Hello Web3 React {list.a}</h1>
    </>
  );
};

export default App;

觀察控制臺(tái),發(fā)現(xiàn)已經(jīng)沒有無意義渲染的提示了,It's wonderful!

  • 注意:Immer 并沒有 Immutable 解決的那么徹底,我們不能直接給draft賦值,而在draft上操作是極好的
useEffect(() => { 
  // setList({ a: 1 });
  setList(draft => {
    draft.a = 1;
  }); 
},[]);

自己動(dòng)手實(shí)現(xiàn)hooks-useImmer

import { useCallback, useState } from 'react';
import { produce, Draft, freeze } from 'immer';

/**
 * 定義函數(shù)的簽名
 * initialState 可以是一個(gè)數(shù)據(jù),也可以是一個(gè)函數(shù)
 * useImmer 返回元組,類似 [state, setState] = useImmer(data);
 * Draft 中間狀態(tài)
 * (() => S) 自執(zhí)行函數(shù)
 */
export type DraftFunction<S> = (draft: Draft<S>) => void;
export type Updater<S> = (arg: S | DraftFunction<S>) => void;
export type ImmerHook<S> = [S, Updater<S>];
export function useImmer<S = any>(initialState: S | (() => S)): ImmerHook<S>;

/**
 * 實(shí)現(xiàn)
 * @param initialState
 */
export function useImmer<T>(initialState: T) {
  // const [state, setState] = useState(initialState);
  // 凍結(jié) state,第二參數(shù) true,表示深度凍結(jié),對(duì)象不能修改了
  const [value, updateValue] = useState(() =>
    freeze(typeof initialState === 'function' ? initialState() : initialState, true)
  );

  // 使用 useCallback,放置組件間傳遞,產(chǎn)生句柄
  return [
    value,
    useCallback((updater: Updater<T>) => {
      if (typeof updater === 'function') {
        updateValue(produce(updater));
      } else {
        updateValue(freeze(updater));
      }
    }, []),
  ];
}

以上就是一文詳解React渲染優(yōu)化之useImmer的詳細(xì)內(nèi)容,更多關(guān)于React渲染優(yōu)化useImmer的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Create?react?app修改webapck配置導(dǎo)入文件alias

    Create?react?app修改webapck配置導(dǎo)入文件alias

    這篇文章主要為大家介紹了Create?react?app修改webapck配置導(dǎo)入文件alias,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • React項(xiàng)目中使用Redux的?react-redux

    React項(xiàng)目中使用Redux的?react-redux

    這篇文章主要介紹了React項(xiàng)目中使用Redux的?react-redux,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09
  • React 條件渲染最佳實(shí)踐小結(jié)(7種)

    React 條件渲染最佳實(shí)踐小結(jié)(7種)

    這篇文章主要介紹了React 條件渲染最佳實(shí)踐小結(jié)(7種),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Vite+React+TypeScript手?jǐn)]TodoList的項(xiàng)目實(shí)踐

    Vite+React+TypeScript手?jǐn)]TodoList的項(xiàng)目實(shí)踐

    本文主要介紹了Vite+React+TypeScript手?jǐn)]TodoList的項(xiàng)目實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • React函數(shù)組件useContext useReducer自定義hooks

    React函數(shù)組件useContext useReducer自定義hooks

    這篇文章主要為大家介紹了React函數(shù)組件useContext useReducer自定義hooks示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • react中Hooks的理解和用法小結(jié)

    react中Hooks的理解和用法小結(jié)

    Hook是 React 16.8 的新增特性,它可以讓你在不編寫class的情況下使用state以及其他的React特性,這篇文章主要介紹了react中Hooks的理解和用法,需要的朋友可以參考下
    2023-05-05
  • 在React頁面重新加載時(shí)保留數(shù)據(jù)的實(shí)現(xiàn)方法總結(jié)

    在React頁面重新加載時(shí)保留數(shù)據(jù)的實(shí)現(xiàn)方法總結(jié)

    在React頁面重新加載時(shí)保留數(shù)據(jù),可以通過多種方法來實(shí)現(xiàn),常見的方法包括使用瀏覽器的本地存儲(chǔ)(Local Storage 或 Session Storage)、URL參數(shù)、以及服務(wù)器端存儲(chǔ)等,本文給大家總結(jié)了一些具體實(shí)現(xiàn)方法,需要的朋友可以參考下
    2024-06-06
  • ReactQuery?渲染優(yōu)化示例詳解

    ReactQuery?渲染優(yōu)化示例詳解

    這篇文章主要為大家介紹了ReactQuery?渲染優(yōu)化示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • 詳解React中key的作用

    詳解React中key的作用

    這篇文章主要介紹了React中key的作用,幫助大家更好的理解和學(xué)習(xí)使用React,感興趣的朋友可以了解下
    2021-04-04
  • React?實(shí)現(xiàn)具備吸頂和吸底功能組件實(shí)例

    React?實(shí)現(xiàn)具備吸頂和吸底功能組件實(shí)例

    這篇文章主要為大家介紹了React?實(shí)現(xiàn)具備吸頂和吸底功能組件實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02

最新評(píng)論

河间市| 临泉县| 育儿| 麻城市| 永丰县| 彩票| 秦安县| 珠海市| 鄂尔多斯市| 平湖市| 呼玛县| 大邑县| 乳源| 星子县| 平塘县| 玉门市| 福州市| 古丈县| 报价| 华安县| 方城县| 江永县| 青河县| 筠连县| 梧州市| 长沙县| 新昌县| 航空| 台北县| 保靖县| 莱州市| 高邑县| 金阳县| 旌德县| 康马县| 定南县| 嘉黎县| 鸡东县| 成都市| 武清区| 偃师市|