乐闻世界logo
搜索文章和话题

How to optimize React components with React.memo and useCallback when callbacks are changing state in the parent

1个答案

1

Problem Answer

Performance optimization in React is crucial for maintaining smooth application performance. Especially when handling complex state updates and component re-renders, React.memo and useCallback are highly effective tools. I will demonstrate how to use these tools to optimize components with a specific example.

React.memo

React.memo is a higher-order component that memoizes components, re-rendering only when props change. This is particularly useful when the parent component's state updates frequently, but these updates do not always affect the child components.

Example Code

Assume there is a ListItem component that displays list item data. If the list item data remains unchanged, we do not want the ListItem to re-render due to other operations in the parent component.

javascript
const ListItem = React.memo(function({ item }) { console.log("Rendering ListItem", item); return <li>{item.name}</li>; });

useCallback

useCallback is a hook that returns a memoized callback function, which only updates when its dependencies change. This is essential when passing callback functions to memoized child components; otherwise, child components may unnecessarily re-render on every parent component render.

Example Code

Assume our application has a parent component containing multiple ListItem components and a button. The button click updates the state, and this state update should not affect the rendering of ListItem.

javascript
function List() { const [items, setItems] = useState([{id: 1, name: "Item 1"}, {id: 2, name: "Item 2"}]); const [counter, setCounter] = useState(0); const incrementCounter = useCallback(() => { setCounter(c => c + 1); }, []); return ( <div> <ul> {items.map(item => ( <ListItem key={item.id} item={item} /> ))} </ul> <button onClick={incrementCounter}>Increment Counter</button> <p>Counter: {counter}</p> </div> ); }

In this example, even when clicking the button updates the counter state, the ListItem component does not re-render because it is wrapped with React.memo, and the callback function incrementCounter is memoized with useCallback, ensuring its identity stability.

Summary

By appropriately using React.memo and useCallback, we can effectively reduce unnecessary component re-renders in React applications, thereby improving performance. This is particularly important for modern web applications handling large data sets and complex interactions. In practice, it is essential to reasonably evaluate the rendering costs of components and the need for optimization.

2024年7月1日 17:58 回复

你的答案