溫馨提示×

溫馨提示×

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

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

怎么解決React中的re-render問題

發布時間:2022-02-01 14:50:33 來源:億速云 閱讀:533 作者:iii 欄目:開發技術

這篇文章主要介紹“怎么解決React中的re-render問題”,在日常操作中,相信很多人在怎么解決React中的re-render問題問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么解決React中的re-render問題”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

re-render?

首先使用我的腳手架:

npm i ykj-cli -g 
ykj init App
cd ./app
yarn 
yarn dev

這樣一個webpack5、TS、React項目就搭建好了

我們目前只有一個APP組件,內部代碼:

import Myy from './myy.jpg';

function App() {
    console.log('render')
    return (
        <div className="app">
            <h2>歡迎使用明源云 - 云空間前端通用腳手架</h2>
            <img src={Myy} alt="" style={{ width: 500, height: 500 }} />
            <h5>
                加入我們:<a>453089136@qq.com</a>
            </h5>
            <h5>微前端,webpack5,TypeScript,React,vite應有盡有</h5>
        </div>
    );
}

export default App;

刷新訪問頁面后,發現控制臺只打印了一次

怎么解決React中的re-render問題

OK,那我們正式開始,加入一些狀態,以及新增一個按鈕和SubApp組件

import { useState } from 'react';
import Myy from './myy.jpg';
import SubApp from './SubApp'
function App() {
    const [state, setState] = useState("Peter");
    return (
        <div className="app">
            <h2>歡迎使用明源云 - 云空間前端通用腳手架</h2>
            <img src={Myy} alt="" style={{ width: 500, height: 500 }} />
            <h5>
                加入我們:<a>453089136@qq.com</a>
            </h5>
            <SubApp state={state} />
            <h5>微前端,webpack5,TypeScript,React,vite應有盡有</h5>
            <button onClick={() => {
                setState('關注公眾號:前端巔峰')
            }}>測試按鈕</button>
        </div>
    );
}

export default App;


//SubApp組件
function SubApp({ state }) {
    console.log('render')
    return <h2>{state}</h2>
}

export default SubApp

這個時候點擊按鈕,又觸發了一次render

多次點擊,發現render只有一次,因為我們此時每次點擊都是將state的值變成

那么,我們嘗試著將state變成一個對象

const [state, setState] = useState({ des: "Peter" });
  <button onClick={() => {
                setState({ des: '關注公眾號:前端巔峰' })
            }}>測試按鈕</button>

神奇的事情發生了,這里每次點擊設置同樣的state,都會觸發子組件render. - 這里就出現了re-render問題,我們其實都是拿的同樣的state,但是卻出現了不必要的render

錯誤的優化

很多同學在使用React過程中會錯誤的使用PureComponentuseEffect以及UseMemo.

這里我們先用錯誤的方式引入useEffect,改造SubApp

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

function SubApp({ state }) {
    const [data, setData] = useState({})
    useEffect(() => {
        console.log('render')
        setData(state)
    }, [state])
    console.log('render')
    return <h2>{data.des}</h2>
}

export default SubApp

這里可以看到,每次點擊按鈕都在不斷render,使用了useEffect竟然失效了。這優化無效~

這里就要談到useEffect的源碼實現,其實useEffectPureComponent等一系列優化手段,大都是使用了Object.is()這個算法。

MDN資料地址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/is

Object.is

Object.is() 方法判斷兩個值是否為同一個值。

value1
被比較的第一個值。
value2
被比較的第二個值。
返回值
一個 Boolean 類型標示兩個參數是否是同一個值。

描述

Object.is() 方法判斷兩個值是否為同一個值。如果滿足以下條件則兩個值相等:

都是 undefined
都是 null
都是 true 或 false
都是相同長度的字符串且相同字符按相同順序排列
都是相同對象(意味著每個對象有同一個引用)
都是數字且
都是 +0
都是 -0
都是 NaN
或都是非零而且非 NaN 且為同一個值
與== (en-US) 運算不同。== 運算符在判斷相等前對兩邊的變量(如果它們不是同一類型) 進行強制轉換 (這種行為的結果會將 "" == false 判斷為 true), 而 Object.is不會強制轉換兩邊的值。

與=== (en-US) 運算也不相同。=== 運算符 (也包括 == 運算符) 將數字 -0 和 +0 視為相等 ,而將Number.NaN 與NaN視為不相等.

合理使用useEffect,解決re-render

如果Props傳入的是一個對象,那么由于React hooks每次更新都會生成一個全新的對象,而這個全新的對象和之前的對象,無法通過Object.is去對比,每次都會不相等。例如:

  const obj1 = {
            name: "peter"
        }
        const obj2 = {
            name: "peter"
        }

        console.log(Object.is(obj1, obj2, 'xx'))

這段代碼永遠輸出都是false,因為obj1和obj2是兩個不同地址的引用對象

但是如果我們換一種方式:

Object.is(obj1.name, obj2.name )

這樣就可以正常比較,永遠輸出ture了

那么我們現在也要在useEffect中類似這樣使用

    useEffect(() => {
        setData(state)
        console.log('render')
    }, [state.des])

這樣我們的useEffect內部回調只會被觸發一次

簡單實現useEffect

網上抄的代碼改造了比較方法:

let _deps;
function useEffect(callback, dependencies) {
  const hasChanged = _deps
    && !dependencies.every((el, i) =>Object.is( el ,_deps[i]))
    || true;
  // 如果 dependencies 不存在,或者 dependencies 有變化,就執行 callback
  if (!dependencies || hasChanged) {
    callback();
    _deps = dependencies;
  }
}

實現邏輯:將傳入的依賴項遍歷,通過Object.is方法與原依賴項的值進行淺對比,如果不一致就執行callback。

到此,關于“怎么解決React中的re-render問題”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

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

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女