簡體   English   中英

React:父組件重新渲染所有子組件,即使是那些在狀態改變時沒有改變的子組件

[英]React: Parent component re-renders all children, even those that haven't changed on state change

我一直無法找到明確的答案,希望這不是重復。

我正在使用 React + Redux 作為一個簡單的聊天應用程序。 該應用程序由 InputBar、MessageList 和 Container 組件組成。 Container(如您所想)包裝了其他兩個組件並連接到商店。 我的消息狀態以及當前消息(用戶當前正在輸入的消息)都保存在 Redux 存儲中。 簡化結構:

class ContainerComponent extends Component {
  ...
  render() {
    return (
      <div id="message-container">
        <MessageList 
          messages={this.props.messages}
        />
        <InputBar 
          currentMessage={this.props.currentMessage}
          updateMessage={this.props.updateMessage}
          onSubmit={this.props.addMessage}
        />
      </div>
    );
  }
}

我在更新當前消息時遇到的問題。 更新當前消息會觸發更新存儲的操作,該操作更新通過容器並返回到 InputBar 組件的道具。

這有效,但是副作用是每次發生這種情況時我的 MessageList 組件都會重新呈現。 MessageList 沒有收到當前消息,也沒有任何更新的理由。 這是一個大問題,因為一旦 MessageList 變大,每次當前消息更新時,應用程序都會明顯變慢。

我已經嘗試直接在 InputBar 組件中設置和更新當前消息狀態(因此完全忽略了 Redux 架構)並且“修復”了問題,但是如果可能的話,我想堅持使用 Redux 設計模式。

我的問題是:

  • 如果父組件被更新,React 是否總是更新該組件內的所有直接子組件?

  • 這里的正確方法是什么?

如果父組件被更新,React 是否總是更新該組件內的所有直接子組件?

不會。 React 只會在shouldComponentUpdate()返回true重新渲染組件。 默認情況下,該方法總是返回true以避免新人出現任何細微的錯誤(正如 William B 指出的那樣,DOM 不會實際更新,除非發生某些變化,從而降低影響)。

為了防止您的子組件不必要地重新渲染,您需要以這樣一種方式實現shouldComponentUpdate方法,它僅在數據實際更改時才返回true 如果this.props.messages總是同一個數組,它可以像這樣簡單:

shouldComponentUpdate(nextProps) {
    return (this.props.messages !== nextProps.messages);
}

您可能還想對消息 ID 進行某種深度比較或比較,這取決於您的要求。

編輯:幾年后,很多人都在使用功能組件。 如果您是這種情況,那么您需要查看React.memo 默認情況下,功能組件每次都會重新渲染,就像類組件的默認行為一樣。 要修改該行為,您可以使用React.memo()並可選擇提供areEqual()函數。

如果父組件被更新,React 是否總是更新該組件內的所有直接子組件? -> 是的,默認情況下,如果 parent 更改其所有直接子項都會重新渲染,但重新渲染不一定會更改實際的 DOM,這就是 React 的工作原理,只有可見的更改才會更新為真實的 DOM。

這里的正確方法是什么? -> 為了防止甚至重新渲染虛擬 DOM 以進一步提高您的性能,您可以遵循以下任何技術:

  1. 應用ShouldComponentUpdate生命周期方法 - 僅當您的子組件基於類時才應用此方法,您需要使用 prev props 值檢查當前 props 值,如果它們為真,則只需返回 false。

  2. 使用純組件-> 這只是上述方法的一個較短版本,同樣適用於基於類的組件

  3. 使用React memo -> 這是防止重新渲染的最好方法,即使你有功能組件,你只需要用 React.memo 包裝你的組件導出,比如: export default React.memo(MessageList)

希望有幫助!

如果父組件 props 發生了變化,它將重新渲染使用React.Component語句創建的所有子React.Component

嘗試將您的<MessageList>組件React.PureComponent以規避這一點。

根據 React 文檔: In the future React may treat shouldComponentUpdate() as a hint rather than a strict directive, and returning false may still result in a re-rendering of the component. 檢查此鏈接以獲取更多信息

希望這可以幫助任何正在尋找解決此問題的正確方法的人。

如果您使用map來渲染子組件並在它們上使用唯一鍵(例如uuid() ),則可以切換回使用 map 中的i作為鍵。 它可能會解決重新渲染問題。

不確定這種方法,但有時它可以解決問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM