1. Basics
It is a high-order component (HOC) used to optimize the performance of function components and avoid unnecessary re-rendering by memorizing component rendering results.
1.1 Basic usage
const MemoizedComponent = (function MyComponent(props) { /* Rendering logic */ });
MemoizedComponent will be re-rendered only if props change
1.2 Usage with comparison function
const MemoizedComponent = (MyComponent, (prevProps, nextProps) => { // Return true means no re-rendering is required // Return false to indicate re-rendering is required return === ; });
2. Usage scenarios
2.1 Pure display components
const ExpensiveComponent = (function ExpensiveComponent({ data }) { // Complex rendering logic return ( <div> {(item => ( <div key={}> <h3>{}</h3> <p>{}</p> </div> ))} </div> ); }); // Parent componentfunction ParentComponent() { const [count, setCount] = useState(0); const data = [/* Large amount of data */]; return ( <div> <button onClick={() => setCount(c => c + 1)}> Count: {count} </button> <ExpensiveComponent data={data} /> </div> ); }
2.2 List item component
const ListItem = (function ListItem({ item, onItemClick }) { (`Rendering item ${}`); return ( <li onClick={() => onItemClick()}> {} </li> ); }); function List({ items }) { const [selectedId, setSelectedId] = useState(null); // Use useCallback to remember the callback function const handleItemClick = useCallback((id) => { setSelectedId(id); }, []); return ( <ul> {(item => ( <ListItem key={} item={item} onItemClick={handleItemClick} /> ))} </ul> ); }
3. useMemo Basics
useMemo is a Hook that memorizes the results of the calculation and avoids repeated expensive calculations every time you render.
3.1 Basic usage
const memoizedValue = useMemo(() => { // Perform calculation and return the result return computeExpensiveValue(a, b); }, [a, b]); // Dependency array,When an empty array is executed only when initialization is performed,No dependency parameter itemstateEach change causes re-execution,Dependency array room,Re-execution will be triggered if the dependency data changes
4. UseMemo usage scenario
4.1 Expensive calculations
function DataAnalytics({ data }) { const processedData = useMemo(() => { // Assume this is a complex data processing function return (item => ({ ...item, processed: expensiveOperation(item) })); }, [data]); // Recalculate only when data changes return ( <div> {(item => ( <div key={}>{}</div> ))} </div> ); }
4.2 Avoid unnecessary re-rendering of child components
function ParentComponent({ items }) { // Memorize props of object or array type const memoizedValue = useMemo(() => ({ data: items, config: { sortBy: 'name', filterBy: 'active' } }), [items]); return <ChildComponent options={memoizedValue} />; }
4.3 Derived state of complex objects
function UserDashboard({ user, transactions }) { // Calculate user statistics const userStats = useMemo(() => { return { totalSpent: ((sum, t) => sum + , 0), averageSpent: ? ((sum, t) => sum + , 0) / : 0, mostFrequentCategory: calculateMostFrequentCategory(transactions) }; }, [transactions]); return ( <div> <UserInfo user={user} /> <UserStatistics stats={userStats} /> </div> ); }
5. Performance Optimization Best Practices
5.1 Reasonable use
// ✅ Good use scenarios: pure components, props rarely changeconst PureComponent = (function PureComponent({ data }) { return <div>{/* Rendering logic */}</div>; }); // ❌ Bad use scenarios: props often changeconst FrequentlyChangingComponent = (function FrequentlyChangingComponent({ date }) { return <div>{()}</div>; });
5.2 Reasonable use of useMemo
// ✅ Good usage scenarios: high calculation overheadconst expensiveValue = useMemo(() => { return someExpensiveOperation(); }, []); // ❌ Bad use scenarios: small calculation overheadconst simpleValue = useMemo(() => { return + 1; }, []); // This situation can be calculated directly
5.3 Use with useCallback
function SearchComponent({ onSearch }) { const [query, setQuery] = useState(''); // Memorize callback function const handleSearch = useCallback(() => { onSearch(query); }, [query, onSearch]); // Memorize the calculation results const searchResults = useMemo(() => { return performExpensiveSearch(query); }, [query]); return ( <div> <input value={query} onChange={e => setQuery()} /> <button onClick={handleSearch}>search</button> <ResultsList results={searchResults} /> </div> ); } // Use Optimize ResultsListconst ResultsList = (function ResultsList({ results }) { return ( <ul> {(result => ( <li key={}>{}</li> ))} </ul> ); });
6. Things to note
Don't over-optimize
- Use memo and useMemo only where you really need it
- Performance measurement verification optimization effect
Correct use of dependencies
- Make sure the dependency array contains all required values
- Avoid too many dependencies causing optimization failure
Avoid using useMemo in loops
// ❌ Error example{(item => { const memoizedValue = useMemo(() => compute(item), [item]); return <div>{memoizedValue}</div>; })}
Consider memory usage
- memo and useMemo will take up extra memory
- Use caution in memory-constrained environments
7. Performance optimization decision process
- First evaluate whether optimization is really needed
- Identify performance issues with React DevTools Profiler
- Choose the right optimization strategy:
- Component re-render optimization: Use
- Calculation result optimization: useMemo
- Callback function optimization: useCallback
- Test optimization effect
- Continuous monitoring of performance
Through rational use and useMemo, we can significantly improve the performance of our React applications. But remember that over-optimization can backfire and should be optimized only when it is actually needed.
This is the end of this article about the use of hooks and useMemo in React. For more related React and useMemo content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!