React?中hooks之?React.memo?和?useMemo用法示例總結(jié)
1. React.memo 基礎(chǔ)
React.memo 是一個(gè)高階組件(HOC),用于優(yōu)化函數(shù)組件的性能,通過記憶組件渲染結(jié)果來避免不必要的重新渲染。
1.1 基本用法
const MemoizedComponent = React.memo(function MyComponent(props) {
/* 渲染邏輯 */
});只有props發(fā)生變化才會(huì)重新渲染MemoizedComponent
1.2 帶有比較函數(shù)的用法
const MemoizedComponent = React.memo(MyComponent, (prevProps, nextProps) => {
// 返回 true 表示不需要重新渲染
// 返回 false 表示需要重新渲染
return prevProps.id === nextProps.id;
});2. React.memo 使用場景
2.1 純展示組件
const ExpensiveComponent = React.memo(function ExpensiveComponent({ data }) {
// 復(fù)雜的渲染邏輯
return (
<div>
{data.map(item => (
<div key={item.id}>
<h3>{item.title}</h3>
<p>{item.description}</p>
</div>
))}
</div>
);
});
// 父組件
function ParentComponent() {
const [count, setCount] = useState(0);
const data = [/* 大量數(shù)據(jù) */];
return (
<div>
<button onClick={() => setCount(c => c + 1)}>
Count: {count}
</button>
<ExpensiveComponent data={data} />
</div>
);
}2.2 列表項(xiàng)組件
const ListItem = React.memo(function ListItem({ item, onItemClick }) {
console.log(`Rendering item ${item.id}`);
return (
<li onClick={() => onItemClick(item.id)}>
{item.name}
</li>
);
});
function List({ items }) {
const [selectedId, setSelectedId] = useState(null);
// 使用 useCallback 來記憶回調(diào)函數(shù)
const handleItemClick = useCallback((id) => {
setSelectedId(id);
}, []);
return (
<ul>
{items.map(item => (
<ListItem
key={item.id}
item={item}
onItemClick={handleItemClick}
/>
))}
</ul>
);
}3. useMemo 基礎(chǔ)
useMemo 是一個(gè) Hook,用于記憶計(jì)算結(jié)果,避免在每次渲染時(shí)重復(fù)進(jìn)行昂貴的計(jì)算。
3.1 基本用法
const memoizedValue = useMemo(() => {
// 進(jìn)行計(jì)算并返回結(jié)果
return computeExpensiveValue(a, b);
}, [a, b]); // 依賴項(xiàng)數(shù)組,空數(shù)組時(shí)只有初始化的時(shí)候執(zhí)行,沒有依賴參數(shù)項(xiàng)state每次變化都會(huì)引起重新執(zhí)行,有依賴數(shù)組室,依賴數(shù)據(jù)發(fā)生變化才會(huì)觸發(fā)重新執(zhí)行4. useMemo 使用場景
4.1 昂貴的計(jì)算
function DataAnalytics({ data }) {
const processedData = useMemo(() => {
// 假設(shè)這是一個(gè)復(fù)雜的數(shù)據(jù)處理函數(shù)
return data.map(item => ({
...item,
processed: expensiveOperation(item)
}));
}, [data]); // 只在 data 改變時(shí)重新計(jì)算
return (
<div>
{processedData.map(item => (
<div key={item.id}>{item.processed}</div>
))}
</div>
);
}4.2 避免子組件不必要的重新渲染
function ParentComponent({ items }) {
// 記憶對(duì)象或數(shù)組類型的 props
const memoizedValue = useMemo(() => ({
data: items,
config: {
sortBy: 'name',
filterBy: 'active'
}
}), [items]);
return <ChildComponent options={memoizedValue} />;
}4.3 復(fù)雜對(duì)象的派生狀態(tài)
function UserDashboard({ user, transactions }) {
// 計(jì)算用戶統(tǒng)計(jì)信息
const userStats = useMemo(() => {
return {
totalSpent: transactions.reduce((sum, t) => sum + t.amount, 0),
averageSpent: transactions.length
? transactions.reduce((sum, t) => sum + t.amount, 0) / transactions.length
: 0,
mostFrequentCategory: calculateMostFrequentCategory(transactions)
};
}, [transactions]);
return (
<div>
<UserInfo user={user} />
<UserStatistics stats={userStats} />
</div>
);
}5. 性能優(yōu)化最佳實(shí)踐
5.1 合理使用 React.memo
// ? 好的使用場景:純組件,props 很少改變
const PureComponent = React.memo(function PureComponent({ data }) {
return <div>{/* 渲染邏輯 */}</div>;
});
// ? 不好的使用場景:props 經(jīng)常變化
const FrequentlyChangingComponent = React.memo(function FrequentlyChangingComponent({ date }) {
return <div>{date.toLocaleTimeString()}</div>;
});5.2 合理使用 useMemo
// ? 好的使用場景:計(jì)算開銷大
const expensiveValue = useMemo(() => {
return someExpensiveOperation(props.data);
}, [props.data]);
// ? 不好的使用場景:計(jì)算開銷小
const simpleValue = useMemo(() => {
return props.value + 1;
}, [props.value]); // 這種情況直接計(jì)算即可5.3 配合 useCallback 使用
function SearchComponent({ onSearch }) {
const [query, setQuery] = useState('');
// 記憶回調(diào)函數(shù)
const handleSearch = useCallback(() => {
onSearch(query);
}, [query, onSearch]);
// 記憶計(jì)算結(jié)果
const searchResults = useMemo(() => {
return performExpensiveSearch(query);
}, [query]);
return (
<div>
<input
value={query}
onChange={e => setQuery(e.target.value)}
/>
<button onClick={handleSearch}>搜索</button>
<ResultsList results={searchResults} />
</div>
);
}
// 使用 React.memo 優(yōu)化 ResultsList
const ResultsList = React.memo(function ResultsList({ results }) {
return (
<ul>
{results.map(result => (
<li key={result.id}>{result.title}</li>
))}
</ul>
);
});6. 注意事項(xiàng)
不要過度優(yōu)化
- 只在真正需要的地方使用 memo 和 useMemo
- 性能測量驗(yàn)證優(yōu)化效果
依賴項(xiàng)的正確使用
- 確保依賴項(xiàng)數(shù)組包含所有需要的值
- 避免依賴項(xiàng)過多導(dǎo)致優(yōu)化失效
避免在循環(huán)中使用 useMemo
// ? 錯(cuò)誤示例
{items.map(item => {
const memoizedValue = useMemo(() => compute(item), [item]);
return <div>{memoizedValue}</div>;
})}考慮內(nèi)存使用
- memo 和 useMemo 會(huì)占用額外的內(nèi)存
- 在內(nèi)存受限的環(huán)境中要謹(jǐn)慎使用
7. 性能優(yōu)化決策流程
- 首先評(píng)估是否真的需要優(yōu)化
- 使用 React DevTools Profiler 識(shí)別性能問題
- 選擇合適的優(yōu)化策略:
- 組件重新渲染優(yōu)化:使用 React.memo
- 計(jì)算結(jié)果優(yōu)化:使用 useMemo
- 回調(diào)函數(shù)優(yōu)化:使用 useCallback
- 測試優(yōu)化效果
- 持續(xù)監(jiān)控性能
通過合理使用 React.memo 和 useMemo,我們可以顯著提升 React 應(yīng)用的性能。但記住,過度優(yōu)化可能會(huì)適得其反,應(yīng)該在實(shí)際需要時(shí)才進(jìn)行優(yōu)化。
到此這篇關(guān)于React 中hooks之 React.memo 和 useMemo用法總結(jié)的文章就介紹到這了,更多相關(guān)React React.memo 和 useMemo內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
React-Native之定時(shí)器Timer的實(shí)現(xiàn)代碼
本篇文章主要介紹了React-Native之定時(shí)器Timer的實(shí)現(xiàn)代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10
react數(shù)據(jù)管理中的setState與Props詳解
setState?是?React?中用于更新組件狀態(tài)(state)的方法,本文給大家介紹react數(shù)據(jù)管理中的setState與Props知識(shí),感興趣的朋友跟隨小編一起看看吧2023-10-10
react?hooks?計(jì)數(shù)器實(shí)現(xiàn)代碼
這篇文章主要介紹了react?hooks計(jì)數(shù)器實(shí)現(xiàn)代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08
React實(shí)現(xiàn)語音識(shí)別并轉(zhuǎn)換功能
在現(xiàn)代 Web 開發(fā)中,語音識(shí)別技術(shù)的應(yīng)用越來越廣泛,本文將介紹如何使用 React 實(shí)現(xiàn)一個(gè)簡單的語音識(shí)別并轉(zhuǎn)換的功能,有需要的小伙伴可以了解下2025-05-05
react實(shí)現(xiàn)組件狀態(tài)緩存的示例代碼
本文主要介紹了react實(shí)現(xiàn)組件狀態(tài)緩存的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02
ReactJS實(shí)現(xiàn)表單的單選多選和反選的示例
本篇文章主要介紹了ReactJS實(shí)現(xiàn)表單的單選多選和反選的示例,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-10-10

