[英]Does a React component deeply compare props to check if rerender is needed?
我想知道在嘗試確定是否需要重新渲染時,擴展React.Component
的React組件React.Component
深深地比較對象。
例如,給定
const Foo = ({ bar }) => {
return <div>{bar.baz}</div>
}
class App extends React.Component {
constructor() {
super()
this.state = { bar: { baz: 1} }
}
render() {
return <Foo bar={this.state.bar} />
}
}
如果內部App
,狀態bar
變為{baz: 2}
確實<Foo />
深深比較以前的支柱bar
和新接收到的支柱?
順便提一下, PureComponent的文檔說
擴展PureComponent ...或者,考慮使用不可變對象來促進嵌套數據的快速比較。
但是沒有詳細介紹。 有任何想法嗎?
除非您自己實現了shouldComponentUpdate
生命周期方法,否則擴展React.Component
的組件React.Component
重新渲染周期之前不會比較道具,它會比較前一個和當前的Virtual DOM來決定重新渲染的內容。
使用React.PureComponent
擴展的組件也不會將prevProps和prevState的狀態與prevState進行深度比較,但是如果需要重新渲染則需要執行淺比較來決定是否需要重新渲染。
對於v16.6.0以后的Functional component
,React引入了一個高階函數React.memo
,可用於使函數組件表現為React.PureComponent
根據文件 :
React.memo
是一個更高階的組件。 它與React.PureComponent
類似,但是對於函數組件而不是類。它可以像
const MyComponent = React.memo(function MyComponent(props) { /* render using props */ });
如果你的函數組件在給定相同的道具的情況下呈現相同的結果,你可以在調用React.memo時將其包裝起來,以便在某些情況下通過記憶結果來提高性能。 這意味着React將跳過渲染組件,並重用最后渲染的結果。
默認情況下,它只會
shallowly compare complex objects
props對象中的shallowly compare complex objects
對象。 如果要控制比較,還可以提供自定義比較函數作為第二個參數。
'Extend PureComponent'被引用脫離了背景。 文檔說的相反,
只有在您希望擁有簡單的道具和狀態時才能擴展PureComponent
因為
React.PureComponent的shouldComponentUpdate()只是淺淺地比較對象。 如果這些包含復雜的數據結構,則可能會產生更深層次差異的假陰性。
React組件不會比較props,除非它們實現了shouldComponentUpdate
,就像PureComponent
一樣。 可以使用完全相同的prop( ===
相等)重新渲染組件。
如果狀態發生變異但未被強制更新(這是反模式),則不會重新渲染子項。
如果狀態發生變異並被強制更新(這是反模式),則會重新呈現子項:
class App extends React.Component {
componentDidMount() {
this.state.bar.baz = 2;
this.setState(state);
}
...
}
為了限制對深度更改的道具的更新, Foo
應該通過深度比較實現shouldComponentUpdate
,例如Lodash isEqual
:
class Foo extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
return !_.isEqual(this.props, nextProps) || this.state !== nextState;
}
...
}
由於深度比較可能代價高昂,因此應運行性能測試以確定其是否提供性能改進。
React非常歡迎不可變狀態和道具,因為它們可以避免這個問題。 如果一個對象以某種方式改變,它應該被另一個對象替換,即狀態更新應該導致新的state
和state.bar
對象:
class App extends React.Component {
componentDidMount() {
this.setState(({ bar })=> ({
bar: { ...bar, baz: 2 }
});
}
...
}
在這種情況下, Foo
需要淺淺地比較它作為prop獲得的bar
對象,因此它可以是PureComponent
或React.memo
(另一個答案解釋)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.