日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

React?組件的狀態下移和內容提升的操作方法_React

作者:前端小二哥 ? 更新時間: 2022-12-24 編程語言

前言

本專欄的另一篇文章,講到了 useMemo 有一定的開銷,不能濫用,本篇文章講解兩個簡單實用的優化組件渲染性能的方法:

  • 狀態下移
  • 內容提升

在講解這兩種方法之前,我們需要先手動創建一個有嚴重渲染性能的組件,如下所示:

import { useState } from 'react';

export default function App() {
  let [color, setColor] = useState('red');
  return (
    <div>
      <input value={color} onChange={(e) => setColor(e.target.value)} />
      <p style={{ color }}>Hello, world!</p>
      <ExpensiveTree />
    </div>
  );
}

function ExpensiveTree() {
  let now = performance.now();
  while (performance.now() - now < 100) {
    // Artificial delay -- do nothing for 100ms
  }
  return <p>I am a very slow component tree.</p>;
}

很顯然,當 App 組件內的狀態發生了改變,ExpensiveTree 組件會 re-render, 事實上 ExpensiveTree 組件的 props、state 并未發生改變,這并不是我們期望的結果,下面將提供兩種簡單的方法,提升組件渲染的性能;

狀態下移

export default function App() {
  let [color, setColor] = useState('red');
  return (
    <div>
      <input value={color} onChange={(e) => setColor(e.target.value)} />
      <p style={{ color }}>Hello, world!</p>
      <ExpensiveTree />
    </div>
  );
}

我們可以看到以上 ExpensiveTree 組件并不依賴 App 組件內部的狀態,因此我們是否可以考慮,將依賴 color 的元素抽離到一個依賴 color 的組件中呢?
下面是實踐后的代碼:

export default function App() {
  return (
    <>
      <Form />
      <ExpensiveTree />
    </>
  );
}

function Form() {
  let [color, setColor] = useState('red');
  return (
    <>
      <input value={color} onChange={(e) => setColor(e.target.value)} />
      <p style={{ color }}>Hello, world!</p>
    </>
  );
}

此時,將依賴 color 的元素提取到了 Form 組件中,Form 組件內部的狀態不再影響 ExpensiveTree 組件的渲染,問題便得到了解決

內容提升

export default function App() {
  let [color, setColor] = useState('red');
  return (
    <div style={{ color }}>
      <input value={color} onChange={(e) => setColor(e.target.value)} />
      <p>Hello, world!</p>
      <ExpensiveTree />
    </div>
  );
}

以上情況是高開銷組件 ExpensiveTree 的父節點依賴 color,此時顯然狀態下移是行不通的,但是還有另外一種辦法:

export default function App() {
  return (
    <ColorPicker>
      <p>Hello, world!</p>
      <ExpensiveTree />
    </ColorPicker>
  );
}

function ColorPicker({ children }) {
  let [color, setColor] = useState("red");
  return (
    <div style={{ color }}>
      <input value={color} onChange={(e) => setColor(e.target.value)} />
      {children}
    </div>
  );
}

此時和狀態提升是完全相反的,將依賴 color 的元素提升到了 ColorPicker 組件中,而不依賴 color 的元素以 children prop 的形式傳入了 ColorPicker ,當組件內部的狀態改變時:

  • ColorPicker 會重新渲染但是它仍然保存著
  • ColorPicker 的 children 屬性未變化 React 并不會訪問那棵子樹。 因此,ExpensiveTree不會重新渲染。

本文提供的方法并不是新的創意,大家一定都有所實踐,但是我想表達的是,相比于濫用 useMemo,我們需要首先考慮使用這兩種提高組件渲染性能的方法;

原文鏈接:https://blog.csdn.net/qq_44588612/article/details/128018188

欄目分類
最近更新