中文字幕一区二区人妻电影,亚洲av无码一区二区乱子伦as ,亚洲精品无码永久在线观看,亚洲成aⅴ人片久青草影院按摩,亚洲黑人巨大videos

跳過(guò)渲染和React中的記憶

發(fā)布于:2021-02-04 11:15:20

0

188

0

React 渲染 組件

在許多情況下,React組件將在不必重新渲染時(shí)重新渲染。

如果渲染的結(jié)果與組件上一次渲染的結(jié)果完全相同,則最好完全跳過(guò)該渲染(協(xié)調(diào))步驟。

基于類(lèi)的組件

shouldComponentUpdate  

在類(lèi)組件中,方法shouldComponentUpdate允許這樣做。

它是在render()之前調(diào)用的生命周期方法。該方法返回一個(gè)布爾值。如果render()可以跳過(guò),這個(gè)布爾值告訴React。

當(dāng)true時(shí),render()將像平常一樣執(zhí)行。

當(dāng)false時(shí),告訴React它可以跳過(guò)執(zhí)行render()。

用下一個(gè)道具和下一個(gè)狀態(tài)調(diào)用shouldComponentUpdate()。這允許復(fù)雜的邏輯,將當(dāng)前的屬性/狀態(tài)與以前的屬性/狀態(tài)進(jìn)行比較,以確定輸出是否不同,因此組件應(yīng)該更新。

默認(rèn)情況下,shouldComponentUpdate()返回true。

完全不指定此方法。

shouldComponentUpdate(nextProps, nextState) {
return true
}

不要依賴(lài)于此來(lái)完全阻止渲染。它現(xiàn)在可能工作,但它可能會(huì)導(dǎo)致錯(cuò)誤,并可能在未來(lái)發(fā)生變化。相反,將其視為一個(gè)反應(yīng)提示,告訴它“您可以安全地跳過(guò)渲染,結(jié)果將與上一個(gè)結(jié)果相同”。

shouldComponentUpdate中的邏輯很快就會(huì)變得非常復(fù)雜,并且容易出錯(cuò)。

在您知道之前,該方法看起來(lái)會(huì)是這樣的。

shouldComponentUpdate(nextProps, nextState) {
 const propsComparison = this.props.a !== nextProps.a && this.props.b !== nextProps.b && this.props.c !== nextProps.c && this.props.d !== nextProps.d
 const stateComparison = this.state.one !== nextState.one && this.state.two !== nextState.two && this.state.three !== nextState.three
return propsComparison && stateComparison
}

我只是想看看有沒(méi)有什么道具或者狀態(tài)改變了,為什么這么難?

React.PureComponent  

React.PureComponent就是這樣!

PureComponent執(zhí)行道具和狀態(tài)的淺表比較(通過(guò)使用Object.is)。

這會(huì)減少跳過(guò)必要更新的可能性(例如,添加新道具時(shí))。

除非您確信需要自定義道具,否則最好選擇PureComponent。

這意味著這兩個(gè)片段是等價(jià)的。

class Driver extends React.Component {
 shouldComponentUpdate() {
   // a shallow comparison of all the props and state
 }
 render() {{this.props.name};
 }
}

class Driver extends React.PureComponent {   render() {{this.props.name};   } }

功能部件

當(dāng)試圖將同樣的優(yōu)化應(yīng)用于函數(shù)組件而不是基于類(lèi)的組件時(shí),問(wèn)題就出現(xiàn)了。函數(shù)組件不能真正跳過(guò)渲染步驟。函數(shù)組件(實(shí)際上只是一個(gè)函數(shù))要么執(zhí)行要么不執(zhí)行

這就是備忘錄有幫助的地方。

備忘錄基本上是一種技術(shù),用于以后記住一些東西。

React不能只記住數(shù)據(jù)片段,它可以記住整個(gè)組件。

React.memo  

React.memo這樣做!

前兩個(gè)示例是針對(duì)基于類(lèi)的組件的,React.memo是針對(duì)函數(shù)組件的。

不像在基于類(lèi)的組件中那樣跳過(guò)渲染步驟,React.memo將重用上次渲染的結(jié)果,而不是計(jì)算新結(jié)果。

// the function component
const Driver = function(props) {
 return{props.name};
};
// exporting the memoized function component
export default React.memo(Driver);

  • 帶有道具的記憶驅(qū)動(dòng)程序組件的初始呈現(xiàn){ name: "Charles Leclerc" }

    • 函數(shù)組件render <p>Charles Leclerc</p>。

  • 道具更改為{ name: "Daniel Ricciardo" }

    • 組件渲染 <p>Daniel Ricciardo</p>

  • 觸發(fā)驅(qū)動(dòng)程序更新的其他更改組件

    • React.memo看到道具沒(méi)有更改。

    • React使用前面的結(jié)果而不是計(jì)算渲染結(jié)果:<p>Daniel Ricciardo</p>

默認(rèn)情況下,React.memoReact.PureComponent相當(dāng),因?yàn)樗鼘?duì)所有道具進(jìn)行了淺層比較(使用對(duì)象.is如果您想獲得更多的控制權(quán)并負(fù)責(zé)比較,React.memo接受第二個(gè)參數(shù),即比較函數(shù)。這使得它在基于類(lèi)的組件中與shouldComponentUpdate相當(dāng)。

比較函數(shù)還返回一個(gè)布爾值。

該布爾值告訴React它是否應(yīng)該使用組件的前一個(gè)結(jié)果,而不是計(jì)算新的結(jié)果。

當(dāng)false時(shí),函數(shù)組件將像平常一樣執(zhí)行。

當(dāng)true時(shí),函數(shù)組件將不執(zhí)行,并且將使用前面的結(jié)果。

小心!這與shouldComponentUpdate相反!

使用上一個(gè)道具和下一個(gè)道具調(diào)用比較函數(shù)。這允許復(fù)雜的邏輯,將當(dāng)前道具與以前的道具進(jìn)行比較,以確定輸出是否不同,因此應(yīng)使用組件的記憶結(jié)果/備忘錄。

// the function component
const Driver = function(props) {
 return{props.name};
};
// the custom comparison function
const comparisonFn = function(prevProps, nextProps) {
 return prevProps.name === nextProps.name;
};
// exporting the memoized function component
export default React.memo(Driver, comparisonFn);

要使用基于類(lèi)的組件擴(kuò)展并行程序:

除非您確信需要自定義比較函數(shù),否則最好使用默認(rèn)行為。

示例

在這個(gè)演示中,有一個(gè)頂級(jí)組件有兩個(gè)狀態(tài),一個(gè)是count和一個(gè)是unusedCount。顧名思義,它仍將被閑置。

您可以通過(guò)按鈕增加countunusedCount。

頂部組件有4個(gè)子組件,所有子組件都將顯示count以及該子組件渲染的次數(shù)。

只有在更新count時(shí),具有上述優(yōu)化之一的組件才會(huì)渲染。當(dāng)更新unusedCount時(shí),其他的也會(huì)渲染。

React.memoReact.useMemo

React.memo是一個(gè)高階組件,因?yàn)樗邮芤粋€(gè)組件并返回新的/記憶的組件。

React.useMemo是一個(gè)hook(它是一個(gè)函數(shù))。它接受一個(gè)函數(shù)并返回所傳遞函數(shù)的記憶返回值。

React.useMemo  

const memoizedValue = React.useMemo(() => computeExpensiveValue(a, b), [a, b]);

React.useMemo接受函數(shù)作為第一個(gè)參數(shù)。此函數(shù)返回的值是React.useMemo將返回的值。只有在必要時(shí)才會(huì)重新計(jì)算。React.useMemo將返回已記憶/已記憶的值(如果沒(méi)有)。

告訴React.useMemo是否應(yīng)該通過(guò)第二個(gè)參數(shù)(數(shù)組)重新計(jì)算結(jié)果。傳遞的函數(shù)返回的值只有在依賴(lài)項(xiàng)數(shù)組中的某些內(nèi)容發(fā)生更改時(shí)才會(huì)再次計(jì)算。不傳遞任何內(nèi)容將導(dǎo)致每次呈現(xiàn)組件時(shí)都計(jì)算該值(并導(dǎo)致函數(shù)運(yùn)行)。

傳遞的函數(shù)中使用的每個(gè)值都應(yīng)包含在依賴(lài)項(xiàng)數(shù)組中。

這將防止許多意外行為。

React團(tuán)隊(duì)創(chuàng)建了一個(gè)ESLint包,eslint-plugin-react-hooks,用于在違反hook規(guī)則時(shí)發(fā)出警告。正在完成的依賴(lài)關(guān)系數(shù)組由該包中名為exhaustive-deps的規(guī)則檢查。

示例

import React from 'react';

function calculatePodiums(name) {
 // very expensive calculation
 return numResult;
}

const Driver = function(props) {
 const numOfPodiums = React.useMemo(() => calculatePodiums(props.name), [
   props.name
 ]);
 return (My name is: {props.name}I drive for: {props.team}I have been on the podium {numOfPodiums} times);
};

  • 使用props的驅(qū)動(dòng)程序組件的初始呈現(xiàn){ name: "Kimi R?ikk?nen", team: "Ferrari" }

    • 函數(shù)組件計(jì)算numOfPodiums并使用該計(jì)算的結(jié)果進(jìn)行呈現(xiàn)。

  • props更改為{ name: "Kimi R?ikk?nen", team: "Alfa Romeo Racing" }

    • React.useMemo看不到依賴(lài)項(xiàng)數(shù)組中的任何內(nèi)容已更改,并且不會(huì)重新計(jì)算numOfPodiums

    • 使用numOfPodiums的memo/membered值。

  • 道具再次更改為{ name: "Antonio Giovinazzi", team: "Alfa Romeo Racing" }

    • React.useMemo 看到依賴(lài)項(xiàng)數(shù)組中發(fā)生了一些變化并計(jì)算 numOfPodiums

    • 并使用新計(jì)算的值。

React.useCallback

這是特定React.useMemo用法的快捷方式。

React.useMemo返回已記憶的值.

React.useCallback返回已記憶的函數(shù).

但值完全可以是函數(shù)!

這意味著這兩個(gè)片段是等價(jià)。

const memoizedFunction = React.useMemo(function() {
 return function doTheThing(a, b) {
   // do the thing
 }
}
}, [a, b])

這將記憶第一個(gè)參數(shù)(函數(shù))返回的值,該值是一個(gè)名為doTheThing。

const memoizedFunction = React.useCallback(function doTheThing(a, b) {
   // do the thing
 }
}, [a, b])

這將記憶第一個(gè)參數(shù),這是一個(gè)名為doTheThing的函數(shù)。

React.useMemo一樣,第二個(gè)參數(shù)是一個(gè)依賴(lài)項(xiàng)數(shù)組。

函數(shù)React.useCallback僅當(dāng)該數(shù)組中的某些內(nèi)容發(fā)生更改時(shí)才會(huì)返回更改。