Array.map((it) => <Component key={it.id} {...it} />)
배열
에다가 item
들을 저장
해서 List 또는 Feed 형태로 렌더링
하는 사례들을 찾아볼 수 있음☑️ src/DiaryList.js : 일기 list를 렌더링할 컴포넌트를 따로 하나 만들기
const DiaryList = ({}) => {
return (
<div className="DiaryList">
<h2>일기 리스트</h2>
</div>
);
};
☑️ src/App.js : DiaryList.js 임포트, DiaryEditor의 자식 요소로 DiaryList 배치
import './App.css';
import DiaryEditor from './DiaryEditor';
import DiaryList from './DiaryList';
function App() {
return (
<div className="App">
<DiaryEditor />
<DiaryList />
</div>
);
}
export default App;
☑️ 일기 저장하기를 누르면 이 밑에 일기 리스트를 추가되도록 하기 위해 예시용으로 임시 배열(dummylist)를 만들어서 DiaryList에 Props로 데이터를 전달, 데이터를 list로 렌더링하기
이 배열은 DiaryList 컴포넌트가 list로 렌더링할 역할은 한다
const dummyList = [
{
id:1,
author: "PERSON 1",
content: "HI 1",
emotion: 5,
create_date: new Date().getTime()
},
{
id:2,
author: "PERSON 2",
content: "HI 2",
emotion: 3,
create_date: new Date().getTime()
},
{
id:3,
author: "PERSON 3",
content: "HI 3",
emotion: 1,
create_date: new Date().getTime()
},
]
☑️ src/App.js : dummyList배열을 DiaryList 컴포넌트에 props으로 전달
function App() {
return (
<div className="App">
<DiaryEditor />
<DiaryList diaryList={dummyList} />
</div>
);
}
☑️ src/DiaryList.js : diaryList에도 props으로 전달하고 콘솔로 확인
☑️ 배열을 리스트로 렌더링 : map() 내장함수
사용 - 원소 한번 씩 순회(각각의 요소들이 div로 리턴한 결과 3개가 있는 배열이 되어 결과값이 된다
)
const DiaryList = ({diaryList}) => {
return (
<div className="DiaryList">
<h2>일기 리스트</h2>
<h4>{diaryList.length} 개의 일기가 있습니다.</h4>
<div>
{diaryList.map((it)=>(
<div>일기 아이템</div>
))}
</div>
</div>
);
};
// 이렇게 나오는 것과 같다
<div>일기 아이템</div>
<div>일기 아이템</div>
<div>일기 아이템</div>
☑️ 데이터를 직접 사용하기 : jsx를 쓰는 법과 같음
const DiaryList = ({diaryList}) => {
return (
<div className="DiaryList">
<h2>일기 리스트</h2>
<h4>{diaryList.length} 개의 일기가 있습니다.</h4>
<div>
{diaryList.map((it)=>(
<div>
<div>작성자 : {it.author}</div>
<div>일기 : {it.content}</div>
<div>감정 : {it.emotion}</div>
<div>작성 시간(ms) : {it.create_date}</div>
</div>
))}
</div>
</div>
);
};
☑️ 배열을 실수로 내려주지 않았다면?
<DiaryList diaryList={undefined} />
DiaryList.defaultProps = { diaryList: [] }
☑️ 고유 id를 활용해 key prop 전달하기
<div>
{diaryList.map((it)=>(
<div key={it.id}> // 자식 아이템의 가장 최상위 태그에 key prop 작성
<div>작성자 : {it.author}</div>
<div>일기 : {it.content}</div>
<div>감정 : {it.emotion}</div>
<div>작성 시간(ms) : {it.create_date}</div>
</div>
))}
</div>
☑️ 만약 고유한 아이디가 없을 경우 map 내장 함수의 콜백 함수에 두번째 파라미터인 index 사용해서 전달하기
<div>
{diaryList.map((it, idx)=>( // idx 몇번째 요소를 순회하고 있는지 가리킴
// s : DiaryItem
<div key={idx}>
<div>작성자 : {it.author}</div>
<div>일기 : {it.content}</div>
<div>감정 : {it.emotion}</div>
<div>작성 시간(ms) : {it.create_date}</div>
</div>
// e : DiaryItem
))}
</div>
☑️ 별도의 컴포넌트로 분할
일기 item을 삭제하거나 수정할 수도 있기 때문에 하나의 컴포넌트로만 쓰게 되면 수정/삭제하는 기능까지 전부 한 곳에 모이기 때문에 별도로 DiaryList 배열 데이터를 사용해서 렌더링하는 DiaryItem이라는 컴포넌트를 분할해주기
src/DiaryList.js (import)
import DiaryItem from './DiaryItem.js';
<div>
{diaryList.map((it)=>(
<DiaryItem key={it.id} {...it} />
// 데이터를 받아서 렌더링하는 요소
// 리스트의 아이템이므로 key를 id로 전달
// 스프레드 연산자를 통해서 일기 하나 객체에 포함된 모든 데이터를 전달
))}
</div>
const DiaryItem = ({ id, author, content, emotion, created_date }) => {
return (
<div className="DiaryItem">
<div className="info">
<span className="author_info">
| 작성자 : {author} | 감정점수 : {emotion} |
</span>
<br />
<span className="date">{new Date(created_date).toLocaleString()}</span>
// new Date로 created_date 객체 생성
// toLocalString()로 시간 ms 변환
</div>
<div className="content">{content}</div>
</div>
);
};
export default DiaryItem;
☑️ CSS Styling
/* List */
.DiaryList { border:1px solid #aaa; padding:20px; margin:20px 0 0 0; }
.DiaryList h2 { text-align:center; }
/* Item */
.DiaryItem { background-color:rgb(240,240,240);margin:0 0 10px 0;padding:20px; }
.DiaryItem .info { border-bottom:1px solid #aaa;margin:0 0 10px 0;padding:0 0 10px 0;}
.DiaryItem .date { color:#aaa; }
.DiaryItem .content { font-weight:600;margin:30px 0; }