[React] 리액트에서 리스트 사용하기
📐 DiaryList 컴포넌트 만들기
-
DiaryList.js 생성
// src > DiaryList.js const DiaryList = () => { return ( <div className="DiaryList"> <h2>일기 리스트</h2> </div> ); }; export default DiaryList;
-
App.js 에 컴포넌트 넣어주기
// src > App.js import { useState, useEffect } from "react"; import "./App.css"; import DiaryEditor from "./DiaryEditor"; import DiaryList from "./DiaryList"; function App() { return ( <div className="App"> <DiaryEditor /> <DiaryList /> </div> ); } export default App;
📐 일기 리스트에 사용될 dummyList 생성
import { useState, useEffect } from "react";
import "./App.css";
import DiaryEditor from "./DiaryEditor";
import DiaryList from "./DiaryList";
const dummyList = [
{
id: 1,
author: "손수경",
content: "하이1",
emotion: 5,
created_date: new Date().getTime(),
},
{
id: 1,
author: "손수경2",
content: "하이2",
emotion: 3,
created_date: new Date().getTime(),
},
{
id: 1,
author: "손수경3",
content: "하이3",
emotion: 4,
created_date: new Date().getTime(),
},
];
function App() {
return (
<div className="App">
<DiaryEditor />
<DiaryList diaryList={dummyList} />
</div>
);
}
export default App;
App.js에서 만든 dummyList prop을 DiaryList 컴포넌트로 전달해주기 위해서 diaryList={dummyList}
를 통해서 전달
📐 DiaryList.js에서 prop 사용하기
📍 접근 방법
const DiaryList = ({ diaryList }) => {
console.log(diaryList);
return (
<div className="DiaryList">
<h2>일기 리스트</h2>
<h4>{diaryList.length}개의 일기가 있습니다.</h4>
<div>
{diaryList.map(
(
it //dummyList의 하나의 객체가 it로 넘어옴
) => (
<div>
<div>작성자 : {it.author}</div>
<div>일기 : {it.content}</div>
<div>감정 : {it.emotion}</div>
<div>작성 시간(ms) : {it.created_date}</div>
</div>
)
)}
</div>
</div>
);
};
export default DiaryList;
- diaryList라는 이름으로 dummyList 전달 -> DiaryList 함수의 매개변수로 받고 있음
- diaryList의 객체 하나씩 접근하기 위해서는 map() 메소드를 사용 -> it는 하나의 객체라고 생각하고 it.author, it.content, it.emotion, it.created_date로 접근
📍 문제점 1.
❓ 만약에 App.js에서 값이 있는 리스트가 prop으로 전달될 줄 알았는데, undefined가 전달되었다면? -> diaryList.length의 길이를 구할 수 없으므로 에러 발생
💡 defaultProps를 사용해서 undefined로 전달될 수 있는 값들의 기본값을 설정해준다. = 배열을 빈 배열로 설정해준다.
DiaryList.defaultProps = {
diaryList: [],
};
📍 문제점 2.
❓ key값이 설정되지 않았다는 에러 발생
💡 1. dummyList에서 설정해두었던 id값을 활용
<div key={it.id}>
<div>작성자 : {it.author}</div>
<div>일기 : {it.content}</div>
<div>감정 : {it.emotion}</div>
<div>작성 시간(ms) : {it.created_date}</div>
</div>
💡 2. map 함수의 매개변수 idx값을 사용
-> 하지만 데이터 삭제, 추가가 발생한다면, 인덱스가 맞지 않아 에러가 발생할 수 있으므로 id값을 사용하자!
📍 문제점 3.
❓ 일기 사용자, 내용 등이 바뀌면 그때마다 일기 내용을 랜더링 해주어야 된다. -> 에러 발생 가능성이 높아짐
💡 DiaryItem.js 컴포넌트를 통해서 기능을 분리할 것
DiaryList가 랜더링하는 자식
<div key={it.id}>
<div>작성자 : {it.author}</div>
<div>일기 : {it.content}</div>
<div>감정 : {it.emotion}</div>
<div>작성 시간(ms) : {it.created_date}</div>
</div>
이 <DiaryItem />
가 될 수 있도록 만들 예정임
📐 DiaryItem.js 만들기
// DiaryList.js -> 리스트를 랜더링하는 컴포넌트
import DiaryItem from "./DiaryItem.js";
const DiaryList = ({ diaryList }) => {
console.log(diaryList);
return (
<div className="DiaryList">
<h2>일기 리스트</h2>
<h4>{diaryList.length}개의 일기가 있습니다.</h4>
<div>
{diaryList.map(
(
it //dummyList의 하나의 객체가 it로 넘어옴
) => (
<DiaryItem key={it.id} {...it} />
)
)}
</div>
</div>
);
};
//undefined로 전달될 수 있는 값들의 기본값을 설정
DiaryList.defaultProps = {
diaryList: [],
};
export default DiaryList;
DiaryList.js 에서 작성 랜더링 부분에 <DiaryItem />
을 넣고 싶은 것이기 때문에 우선 import를 해준다. 그리고 DiaryList 컴포넌트에서는 id, author, content, emotion, created_date를 전달해주어야 된다. -> spread 연산자 활용
const DiaryItem = ({ author, content, created_date, emotion, id }) => {
return (
<div className="DiaryItem">
<div className="info">
<span>
작성자 : {author} | 감정점수 : {emotion} |
</span>
<br />
<span className="date"> {new Date(created_date).toLocaleString()}</span>
</div>
<div className="content">{content}</div>
<br />
</div>
);
};
export default DiaryItem;
DiaryItem 함수 설명
{ author, content, created_date, emotion, id }
: 부모 컴포넌트에서 spread 연산자를 통해서 전달된 값을 전달받는다.{author}, {content}, ,,,
: 전달받은 값을 DiaryItem 컴포넌트에서 사용하는 방법{new Date(created_date).toLocaleString()}
: ms을 시간, 분, 초로 바꾸어 준다.
📐 스타일링
// App.css
...
/* List */
.DiaryList {
border: 1px solid gray;
padding: 20px;
margin-top: 20px;
}
.DiaryList h2 {
text-align: center;
}
/*Item*/
.DiaryItem {
background-color: rgb(240, 240, 240);
margin-bottom: 10px;
padding: 20px;
border-radius: 20px;
}
.DiaryItem .info {
border-bottom: 1px solid gray;
padding-bottom: 10px;
margin-bottom: 10px;
}
.DiaryItem .date {
color: gray;
}
.DiaryItem .content {
font-weight: bold;
margin-bottom: 30px;
margin-top: 30px;
}
댓글남기기