React中如何渲染新消息而不重渲染历史消息?
Hey there! Let's break down why all your old messages are re-rendering when you add a new one, and fix that performance issue right away.
问题根源
Right now, you're rendering each message directly inside the App component. Whenever the messageArr state updates (when you add a new message), the entire App component re-renders. Since all your message elements are direct children of App, they all get re-rendered too—even the old ones that haven't changed at all. That's why you see console logs for messages 1-3 when you add message 4.
解决方案:用React.memo缓存消息组件
The fix is to extract your individual message into a separate component, and wrap it with React.memo. This tells React to skip re-rendering the component unless its props have changed. Since old messages' content (and id) never change, they won't re-render when new messages are added.
Step 1: 创建Memoized的Message组件
Create a new file Message.js with this code:
import React from 'react'; // React.memo will memoize this component to avoid unnecessary re-renders const Message = React.memo(({ message }) => { console.log(message); // Only logs when this message's props change return <li>{message}</li>; }); export default Message;
Step 2: 修改App组件使用这个新组件
Update your App.js to use the Message component instead of rendering the <li> directly:
import { useState } from 'react'; import Form from './Form'; import Message from './Message'; const App = () => { const [messageArr, setMessageArr] = useState([]); const addMessage = (messageText) => { setMessageArr([...messageArr, messageText]); }; return ( <div> <ul> {messageArr.map(({ id, message }) => ( // Move the key to the Message component (React best practice for lists) <Message key={id} message={message} /> ))} </ul> <Form addMessage={addMessage} /> </div> ) }; export default App;
为什么这样有效?
React.memo does a shallow comparison of the component's props. For your old messages, the message prop never changes, so React skips re-rendering those components entirely. Only the new Message component (for the latest message) will render, and you'll only see its console log when you add a new entry.
额外优化小提示
You can remove the extra <div> wrapper around the message—placing the key directly on the Message component is cleaner and follows React's best practices for list rendering.
内容的提问来源于stack exchange,提问作者vijay-navale

