인프런 커뮤니티 질문&답변

hws9701님의 프로필 이미지
hws9701

작성한 질문수

처음 만난 리액트(React)

(실습) Card 컴포넌트 만들기

[Card 컴포넌트 만들기 강의] 코드질문 있습니다!

해결된 질문

작성

·

530

2

강의 너무 잘 보고 배우고 있습니다!! 감사합니다 🙂

  1. 카드를 한장이 아니라 여러 장이 나오게 만들고 싶어서 혼자 코드를 수정해봤는데요 key 값이 없어서 오류가 난다고 하는데요

     

    1-1.이 상태에서는 어떻게 key값을 넣어줘야 할까요?
    1-2. 다른 방법은 없을까요?

import Card from "./Card";

const names = [
    {
        id: 1, 
        name: "학생 1",
        comment: "리액트 공부중입니다"
    },
    {
        id:2,
        name: "학생 2",
        comment: "리액트 공부중임니댜"
    }
]

function ProfileCard(props) {
    <div>
    {names.map((name) => {
    return (
        <Card title={name.name} backgroundColor="#B57EDC" comment={name.comment} />
        )
    })};
    </div>
}

export default ProfileCard;

답변 1

1

Inje Lee (소플)님의 프로필 이미지
Inje Lee (소플)
지식공유자

안녕하세요, 소플입니다.

질문해주신 내용에 대해 답변드립니다.

 

1-1. key 값을 어떻게 넣어야 하는지?

key값은 map() 함수에서 리턴하는 가장 상위 element에 넣어주면 됩니다.

지금 작성하신 코드의 경우에는 id라는 고유한 값이 있으니, 그걸 사용해서 아래와 같이 넣어주면 됩니다.

import Card from './Card';

const names = [
    {
        id: 1,
        name: '학생 1',
        comment: '리액트 공부중입니다.',
    },
    {
        id: 2,
        name: '학생 2',
        comment: '리액트 공부중입니다.',
    },
];

function ProfileCard(props) {
    <div>
        {names.map((name) => {
            return (
                <Card
                    key={name.id}
                    title={name.name}
                    backgroundColor='#B57EDC'
                    comment={name.comment}
                />
            );
        })}
    </div>;
}

export default ProfileCard;

여기서 입문자 분들이 주로 헷갈리시는 부분은,

내가 만든 컴포넌트(Card)에는 key라는 prop을 따로 정의하지 않았는데 key라는 prop을 넣어도 되나?

라는 부분입니다.

하지만 key라는 속성은 리액트에서 배열 내에 있는 element들에게 기본적으로 제공하는 속성이기 때문에,

개발자가 별도로 정의하지 않고 사용해도 됩니다.

다만, key값은 리액트 내부적으로만 사용되며 컴포넌트의 prop으로 전달하여 사용할 수 없습니다.

(이미 예약되어 있는 속성이라고 생각하시면 됩니다.)

 

1-2. 다른 방법은 없는지?

여기서 말씀하시는 다른 방법이 어떤 것을 의미하는지 정확하게 모르겠지만,

key값으로는 고유한 값이라면 다 사용할 수 있습니다.

대표적으로는 아래와 같이 변수의 값, index, id, 문자열 조합 등이 있습니다.

// id를 사용한 경우
function ProfileCard(props) {
    return (
        <div>
            {names.map((name, index) => {
                return (
                    <Card
                        key={name.id}
                        title={name.name}
                        backgroundColor='#B57EDC'
                        comment={name.comment}
                    />
                );
            })}
        </div>
    );
}

// 값을 사용한 경우
function ProfileCard(props) {
    return (
        <div>
            {names.map((name, index) => {
                return (
                    <Card
                        key={name.name}
                        title={name.name}
                        backgroundColor='#B57EDC'
                        comment={name.comment}
                    />
                );
            })}
        </div>
    );
}

// index를 사용한 경우
function ProfileCard(props) {
    return (
        <div>
            {names.map((name, index) => {
                return (
                    <Card
                        key={index}
                        title={name.name}
                        backgroundColor='#B57EDC'
                        comment={name.comment}
                    />
                );
            })}
        </div>
    );
}

// 문자열 조합을 사용한 경우
function ProfileCard(props) {
    return (
        <div>
            {names.map((name, index) => {
                return (
                    <Card
                        key={`item-${name.id}`}
                        title={name.name}
                        backgroundColor='#B57EDC'
                        comment={name.comment}
                    />
                );
            })}
        </div>
    );
}

 

추가로 아래 리액트 공식 문서를 읽어보시면 더 확실하게 이해하실 수 있을 겁니다😀

https://react.dev/learn/rendering-lists#why-does-react-need-keys

 

감사합니다.

hws9701님의 프로필 이미지
hws9701
질문자

답변 너무 감사드립니다.
그런데 알려주신 모든 방법을 해봤는데 에러는 안나지만 계속 빈화면만 나옵니다ㅠㅠ 어떻게 해결해야할까요?

Inje Lee (소플)님의 프로필 이미지
Inje Lee (소플)
지식공유자

화면에 아무것도 나오지 않는다면 다른 코드에 문제가 있을 것 같습니다.

혹시 index.js 등 다른 부분의 코드도 공유해주실 수 있을까요?

hws9701님의 프로필 이미지
hws9701
질문자

1.index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
// import App from './App';
import reportWebVitals from './reportWebVitals';
import ProfileCard from './chapter_13/ProfileCard';
// import Calculator from './chapter_12/Calculator';
// import SignUp from './chapter_11/SignUp';
// import LandingPage from './chapter_09/LandingPage';
// import AttendanceBook from './chapter_10/AttendanceBook';
// import ConfirmButton from './chapter_08/ConfirmButton';
// import Library from './chapter_03/Library';
// import Clock from './chapter_04/clock';
// import CommentList from './chapter_05/CommentList';
// import NotificationList from './chapter_06/NotificationList';
// import Accommodate from './chapter_07/Accommodate';



const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <ProfileCard />
  </React.StrictMode>
);


// 시계만들기(chapter_04)
// setInterval(() => {
//   root.render(
//     <React.StrictMode>
//       <Clock />
//     </React.StrictMode>
//   );
// }, 1000);


// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
hws9701님의 프로필 이미지
hws9701
질문자

  1. Card.jsx 는 이렇게 해두었습니다!!

function Card(props) {
    const { title, backgroundColor, children } = props;

    return (
        <div
            style={{
                margin: 8,
                padding: 8,
                borderRadius: 8,
                boxShadow: "0px 0px 4px grey",
                backgroundColor: backgroundColor || "white",
            }}
        >
            {title && <h1>{title}</h1>}
            {children}
        </div>
    );
}

export default Card;
Inje Lee (소플)님의 프로필 이미지
Inje Lee (소플)
지식공유자

아 처음 코드를 다시 자세히 보니 return이 빠져있네요~

아래와 같이 수정해서 해보시기 바랍니다!

function ProfileCard(props) {
    return (
        <div>
            {names.map((name) => {
                return (
                    <Card
                        key={name.id}
                        title={name.name}
                        backgroundColor='#B57EDC'
                        comment={name.comment}
                    />
                );
            })}
        </div>
    );
}

export default ProfileCard;
hws9701님의 프로필 이미지
hws9701
질문자

우오 해결되었습니다!! 감사합니다!!

comment 도 나오게 하려면 children={name.comment}로 해야하네욥 ㅎㅎ

덕분에 해결하였습니다 늦은시간에 답변 이렇게 빨리 해주셔서 너무 감사드립니다ㅠㅠㅠ

hws9701님의 프로필 이미지
hws9701

작성한 질문수

질문하기