I would like to render only newly added elements instead of re-rendering the entire list when a new element gets added to the list. I tried adding key prop but still all elements are rendering. This is an example code for my use-case https://codesandbox.io/s/jovial-poincare-qcsvn?file=/src/App.js, here we can see console log for all list elements when we add a new element to the list.
CodePudding user response:
It happens because you defined your CommentView component inside the App Component any update on the state cause the component to be re-render and react treats these CommentView recreated version as it is a completely different component lets assume react think you change the div to span it has no idea they are the same old component
Hoist the component outside the App component
const CommentView = React.memo(/**/)
const App = () => {/* rest without the CommentView definition */}
you can also use Pure component instead of memo if you want, which compare shallowly
class CommentView extends PureComponent {
render() {
const comment = this.props.comment;
return (
<h1 key={`comment-${comment.id}`}>
{console.log("Rendering", comment.id)}
{comment.id}: {comment.msg}
</h1>
);
}
}
export default function App() {
// rest of code
CodePudding user response:
First of all, your id is not unique. If you add this, it will be unique:
{
id: comments[comments.length - 1].id 1,
msg: "C"
}
Changing the state means that React triggers an update when we call the setState
function (in React hooks, you would use useState
). This doesn't only mean the component's render function will be called, but also that all its subsequent child components will re-render, regardless of whether their props have changed or not.
React.memo
only does the shallow comparison.
So you need to supply your own comparison logic as a second parameter.
function MyComponent(props) {
/* render using props */
}
function areEqual(prevProps, nextProps) {
/*
return true if passing nextProps to render would return
the same result as passing prevProps to render,
otherwise return false
*/
}
export default React.memo(MyComponent, areEqual);