[React] 배열 사용하기 1 -리스트 렌더링 (조회)

이재훈·2023년 6월 7일
0

React

목록 보기
8/27

목표

React에서 리스트 렌더링하기

  • 배열을 이용하여 React에서 List를 렌더링하고 개별적인 컴포넌트 만들어보기

먼저 list 배열을 props로 넘겨서 DiaryList.js에서 그 데이터로 렌더링을 해보도록 하겠습니다.

App.js


import './App.css';
import DiaryEditor from './DiaryEditor';
import DiaryList from './DiaryList';

const dummyList = [
  {
    id:1,
    name: 'jay',
    content: 'hi 1',
    hungry: 10,
    created_date: new Date().getTime()
  },
  {
    id:2,
    name: 'jay2',
    content: 'hi 2',
    hungry: 20,
    created_date: new Date().getTime()
  },
  {
    id:3,
    name: 'jay3',
    content: 'hi 3',
    hungry: 10,
    created_date: new Date().getTime()
  },
  {
    id:4,
    name: 'jay4',
    content: 'hi 4',
    hungry: 40,
    created_date: new Date().getTime()
  },
]

function App() {
  return (
    <div className="App">
      <DiaryEditor/>
      <DiaryList diaryList={dummyList}/>
    </div>
  );
}

export default App;

DiaryList.js

const DiaryList = ({ diaryList }) => {
    console.log(diaryList)
    return (
        <div className="DiaryList">
            <h2>일기 리스트</h2>
        </div>
    );
};

export default DiaryList;


props로 데이터를 잘 넘긴 것을 확인할 수 있습니다.

DiaryList.js

const DiaryList = ({ diaryList }) => {
  return (
    <div className="DiaryList">
      <h2>일기 리스트</h2>
      <h4>{diaryList.length}개의 일기가 존재합니다.</h4>
      <div>
        {diaryList.map((it) => (
          <div>
            <div>작성자 : {it.name}</div>
            <div>내용 : {it.content}</div>
            <div>배고픔 정도 : {it.hungry}</div>
            <div>작성 시간 : {it.created_date}ms</div>
          </div>
        ))}
      </div>
    </div>
  );
};

export default DiaryList;

매개변수로 diaryList를 받고 그 값을 map 함수를 사용하여 각 데이터에 접근이 가능합니다. 세부적인 데이터 접근은 점 표기법을 사용하여 ui에 나타내보았습니다.

매개변수로 받은 diaryList가 undefined 일 수 있기 때문에 defaultProps를 사용해서 에러를 방지하도록 하겠습니다.

const DiaryList = ({ diaryList }) => {
  return (
    <div className="DiaryList">
      <h2>일기 리스트</h2>
      <h4>{diaryList.length}개의 일기가 존재합니다.</h4>
      <div>
        {diaryList.map((it) => (
          <div>
            <div>작성자 : {it.name}</div>
            <div>내용 : {it.content}</div>
            <div>배고픔 정도 : {it.hungry}</div>
            <div>작성 시간 : {it.created_date}ms</div>
          </div>
        ))}
      </div>
    </div>
  );
};

DiaryList.defaultProps = {
  diaryList: [],
};

export default DiaryList;


props로 undifined를 넘겨도 에러가 발생하지 않는 것을 확인할 수 있습니다.

하지만 콘솔에 에러가 찍혀있는 것을 확인할 수 있습니다. "자식 컴포넌트가 key prop를 받아야 한다는 것입니다."

더미 데이터의 고유 id인 id로 자식 아이템의 최상위 태그에 key를 설정해주면 됩니다.

DiaryList.js

const DiaryList = ({ diaryList }) => {
  return (
    <div className="DiaryList">
      <h2>일기 리스트</h2>
      <h4>{diaryList.length}개의 일기가 존재합니다.</h4>
      <div>
        {diaryList.map((it) => (
          <div key={it.id}>
            <div>작성자 : {it.name}</div>
            <div>내용 : {it.content}</div>
            <div>배고픔 정도 : {it.hungry}</div>
            <div>작성 시간 : {it.created_date}ms</div>
          </div>
        ))}
      </div>
    </div>
  );
};

DiaryList.defaultProps = {
  diaryList: [],
};

export default DiaryList;

콘솔에 에러가 사라진 것을 확인할 수 있습니다.

만약 넘겨진 props의 고유한 id가 없다면 ?? 아래 방법을 사용하면 됩니다.

      <div>
        {diaryList.map((it, idx) => (
          <div key={idx}>
            <div>작성자 : {it.name}</div>
            <div>내용 : {it.content}</div>
            <div>배고픔 정도 : {it.hungry}</div>
            <div>작성 시간 : {it.created_date}ms</div>
          </div>
        ))}
      </div>

몇번째 요소를 순회하고 있는지를 나타내는 idx를 사용하여 key 설정이 가능합니다.
하지만 이것은 배열의 순서를 나타내는 것이기 때문에 react에서 삭제, 추가 등의 작업을 하는 과정에서 문제가 생길 수 있습니다. 고유한 아이디를 가지고 idx를 사용하지 않는 것을 권장합니다.

현재 코드의 문제

현재는 diaryList에 map을 사용하여 리스트 아이템들을 렌더링하고 있습니다. 목표는 일기 프로젝트를 삭제, 수정도 가능해야 합니다. 그 기능들이 DiaryList.js에 추가된다면 너무 많은 기능이 DiaryList.js에 들어가게 되는 것입니다. 이것은 좋지 않은 방법이므로 diaryList 배열 데이터를 렌더링하는 item을 별도로 분할하도록 하겠습니다.

DiaryList.js

import DiaryItem from "./DiaryItem";

const DiaryList = ({ diaryList }) => {
  return (
    <div className="DiaryList">
      <h2>일기 리스트</h2>
      <h4>{diaryList.length}개의 일기가 존재합니다.</h4>
      <div>
        {diaryList.map((it) => (
          <DiaryItem key={it.id} {...it} />
        ))}
      </div>
    </div>
  );
};

DiaryList.defaultProps = {
  diaryList: [],
};

export default DiaryList;

DiaryList에서 key로 id를 , 그리고 나머지를 스프레드 연산자로 props를 넘겨주었습니다.

DiaryItem.js

const DiaryItem = ({ name, content, created_date, hungry, id }) => {
  return (
    <div className="DiaryItem">
      <div className="info">
        <span>
          이름 : {name} | 배고픔 정도 : {hungry}
        </span>
        <br />
        <span className="date">{new Date(created_date).toLocaleString()}</span>
      </div>
      <div className="content">{content}</div>
    </div>
  );
};

export default DiaryItem;

비구조화 할당으로 받은 데이터를 보여주는 코드입니다.

<span className="date">{new Date(created_date).toLocaleString()}</span>

created_date는 ms로 받았기 때문에 사람이 읽을 수 있는 형식으로 바꿔주었습니다.

css를 추가하고

App.css

.DiaryEditor {
  border: 1px solid blueviolet;
  text-align: center;
  padding: 20px;
}

.DiaryEditor input,
textarea {
  margin-bottom: 20px;
  width: 500px;
  padding: 10px;
}

.DiaryEditor textarea {
  height: 150px;
}

.DiaryEditor select {
  width: 60px;
  padding: 10px;
  margin-bottom: 20px;
  margin-left: 30px;
}

.DiaryEditor button {
  width: 500px;
  height: 50px;
  cursor: pointer;
  background-color: blueviolet;
}

/* List */

.DiaryList {
  border: 1px solid blueviolet;
  padding: 20px;
  margin-top: 20px;
}

.DiaryList h2 {
  text-align: center;
}

/* item */
.DiaryItem {
  background-color: lightskyblue;
  margin-bottom: 10px;
  padding: 20px;
}

.DiaryItem .info {
  border-bottom: 1px solid blue;
  padding-bottom: 10px;
  margin-bottom: 10px;
}

.DiaryItem .date {
  color: gray;
}

.DiaryItem .content {
  font-weight: bold;
  margin-bottom: 30px;
  margin-top: 30px;
}

css도 잘 적용 된 것을 확인할 수 있습니다. 다크모드를 사용하니 css가 잘 안보여서 마지막 캡쳐는 다크모드를 풀고 캡쳐했습니다.


해당 게시글은 인프런 강의
"한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지(이정환)"
를 정리한 내용입니다. 쉽게 잘 설명해주시니 여러분도 강의를 듣는 것을 추천드립니다.

profile
부족함을 인정하고 노력하자

0개의 댓글