Search code examples
javascriptreactjsreduxnext.jsantd

Questions about antd's unique key and component structure


I'm working on a project using react, next.js, antd.

However, the following error occurred:

Warning: Each child in a list should have a unique "key" prop.

We know that the following error occurs because the list's child element does not have a unique key.

So, I tried to fix the code where the error occurred by using the following methods, but it was not resolved.

const BoardList = () => {
  const { boardPosts } = useSelector((state) => state.user);

  return (
    <section>
      <List  
          itemLayout="vertical"
          bordered    
          size="large"
          pagination={{
            onChange: (page) => console.log(page), pageSize: 3,
          }}
          dataSource={boardPosts}    
          renderItem={(item) => (  
            <List.Item key={item.id}>
              <BoardCard post={item}  />
            </List.Item>         
        )}
      />          
    </section>
  )
};
------------------------------
try 0.
<List.Item>
  <BoardCard post={item} key={item.id} />
</List.Item>  

try 1.
<List.Item key={item.id}>
  <BoardCard post={item}  />
</List.Item>         

try 2.
renderItem={(item, i) => (  
  <List.Item key={i}>
    <BoardCard post={item}  />
  </List.Item>         

try 3.
<List.Item>
  <div key={item.id}>
    <BoardCard post={item} /> 
  </div>  
</List.Item>         

try 4.
<div key={item.id}>
  <List.Item>
    <BoardCard post={item} /> 
  </List.Item>         
</div>

So I start to doubt whether the above problem is a problem with the component structure.

The component where the problem occurred consists of the following three components.

// pages/profile
import React from 'react';

import NicknameEditForm from './NicknameEditForm';
import MyScrap from './MyScrap';
import MyBoard from './MyBoard';

const MyInfo = () => { 
  return (   
    <section>
      <NicknameEditForm /> // A component that changes a member's nickname
      <MyScrap /> // Gets the post that has been liked from the POST table.
      <MyBoard /> // I get the post I wrote from the POST table.        
    </section> 
  )
};

export default MyInfo;
// MyScrap.js
const { likedPosts } = useSelector((state) => state.post);

// MyBoard.js
const { boardPosts } = useSelector((state) => state.post);

Also, MyScrap and MyBoard components receive the following data from the backend and use it.

// likedPosts used in MyScrap component
likedPosts = [{id: 1, title: 'title1',.....}, [...] ...]

// boardPosts used in MyBoard component
boardPosts = [{id: 1, title: 'title1',.....}, [...] ...]

So, I wonder if the following problem occurred because the key values of MyScrap component and MyBoard component overlap due to the following structure on one page or if there is another reason.


Solution

  • Try using rowKey in List component. You can check the example here

    const BoardList = () => {
      const { boardPosts } = useSelector((state) => state.user);
    
      return (
        <section>
          <List  
              itemLayout="vertical"
              bordered    
              size="large"
              rowKey={(item) => item.id}
              pagination={{
                onChange: (page) => console.log(page), pageSize: 3,
              }}
              dataSource={boardPosts}    
              renderItem={(item) => (  
                <List.Item>
                  <BoardCard post={item}  />
                </List.Item>         
            )}
          />          
        </section>
      )
    };