React 組件的狀態(tài)下移和內(nèi)容提升的操作方法
前言
本專欄的另一篇文章,講到了 useMemo 有一定的開銷,不能濫用,本篇文章講解兩個簡單實用的優(yōu)化組件渲染性能的方法:
- 狀態(tài)下移
- 內(nèi)容提升
在講解這兩種方法之前,我們需要先手動創(chuàng)建一個有嚴重渲染性能的組件,如下所示:
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>; }
很顯然,當(dāng) App 組件內(nèi)的狀態(tài)發(fā)生了改變,ExpensiveTree 組件會 re-render, 事實上 ExpensiveTree 組件的 props、state 并未發(fā)生改變,這并不是我們期望的結(jié)果,下面將提供兩種簡單的方法,提升組件渲染的性能;
狀態(tài)下移
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 組件內(nèi)部的狀態(tài),因此我們是否可以考慮,將依賴 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 組件中,F(xiàn)orm 組件內(nèi)部的狀態(tài)不再影響 ExpensiveTree 組件的渲染,問題便得到了解決
內(nèi)容提升
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 的父節(jié)點依賴 color,此時顯然狀態(tài)下移是行不通的,但是還有另外一種辦法:
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> ); }
此時和狀態(tài)提升是完全相反的,將依賴 color 的元素提升到了 ColorPicker 組件中,而不依賴 color 的元素以 children prop 的形式傳入了 ColorPicker ,當(dāng)組件內(nèi)部的狀態(tài)改變時:
- ColorPicker 會重新渲染但是它仍然保存著
- ColorPicker 的 children 屬性未變化 React 并不會訪問那棵子樹。 因此,ExpensiveTree不會重新渲染。
本文提供的方法并不是新的創(chuàng)意,大家一定都有所實踐,但是我想表達的是,相比于濫用 useMemo,我們需要首先考慮使用這兩種提高組件渲染性能的方法;
到此這篇關(guān)于React 組件的狀態(tài)下移和內(nèi)容提升的文章就介紹到這了,更多相關(guān)React 組件狀態(tài)下移內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Webpack 4.x搭建react開發(fā)環(huán)境的方法步驟
這篇文章主要介紹了Webpack 4.x搭建react開發(fā)環(huán)境的方法步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08關(guān)于React動態(tài)修改元素樣式的三種方式
這篇文章主要介紹了關(guān)于React動態(tài)修改元素樣式的三種方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08react?hooks?d3實現(xiàn)企查查股權(quán)穿透圖結(jié)構(gòu)圖效果詳解
這篇文章主要為大家介紹了react?hooks?d3實現(xiàn)企查查股權(quán)穿透圖結(jié)構(gòu)圖效果詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-01-01詳解使用create-react-app快速構(gòu)建React開發(fā)環(huán)境
這篇文章主要介紹了詳解使用create-react-app快速構(gòu)建React開發(fā)環(huán)境,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-05-05React生命周期方法之componentDidMount的使用
這篇文章主要介紹了React生命周期方法之componentDidMount的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06React項目中應(yīng)用TypeScript的實現(xiàn)
TypeScript通常都會依賴于框架,例如和vue、react 這些框架結(jié)合,本文就主要介紹了React項目中應(yīng)用TypeScript的實現(xiàn),分享給大家,具體如下:2021-09-09