[React] 리액트에서 데이터 삭제하기
🔮 삭제하기 버튼은 어떻게 구현?
- hope : 삭제하기 버튼을 출력되는 일기 리스트 하나 당 제일 아래에 부분에 넣고 싶다.
- 현재 컴포넌트 계층 구조 상태
- App.js
- DiarEditor.js (일기를 입력받는 곳)
- DiaryList.js (저장 후 일기 리스트가 출력될 곳의 공간을 차지, data들을 하나씩 map함수를 이용해서 DiaryItem으로 전달)
- DiaryItem.js (실제 저장된 일기 하나 를 출력할 수 있는 곳)
- App.js
💡 How? -> step 1. 삭제 버튼 구현하기
📐 DiaryItem.js에 버튼 구현
// DiaryItem.js
const DiaryItem = ({
onDelete,
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>
<button
onClick={() => {
console.log(id);
}}
>
삭제하기
</button>
</div>
);
};
export default DiaryItem;
📐 삭제 버튼 동작하기
이 버튼이 동작하기 위해서는 1️⃣ App.js 에서 onDelete 함수를 구현해서 DiaryList.js 까지 전달해주고, 2️⃣ DiaryList.js 컴포넌트를 거쳐서 3️⃣ DiaryItem.js 까지 전달이 되어야 한다.
-
1️⃣ App.js에서 DiaryList에 onDelete 함수를 prop으로 전달
// App.js const onDelete = (targetId) => { console.log(targetId + "가 삭제되었습니다."); }; return ( <div className="App"> <DiaryEditor onCreate={onCreate} /> <DiaryList diaryList={data} onDelete={onDelete} /> </div> );
-
2️⃣ 프롭을 매개변수를 통해서 전달 받고, 다시 DiaryItem으로 전달
// DiaryList.js import DiaryItem from "./DiaryItem.js"; const DiaryList = ({ diaryList, onDelete }) => { console.log(diaryList); return ( <div className="DiaryList"> <h2>일기 리스트</h2> <h4>{diaryList.length}개의 일기가 있습니다.</h4> <div> //dummyList의 하나의 객체가 it로 넘어옴 {diaryList.map( ( it ) => ( <DiaryItem key={it.id} {...it} onDelete={onDelete} /> ) )} </div> </div> ); }; //undefined로 전달될 수 있는 값들의 기본값을 설정 DiaryList.defaultProps = { diaryList: [], }; export default DiaryList;
-
3️⃣ 전달 받은 onDelete 함수를 사용
// DiaryItem.js const DiaryItem = ({ onDelete, 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> <button onClick={() => { console.log(id); //window.confirm은 alert처럼 뜨지만 밑에 확인, 취소 버튼이 같이 뜬다. if (window.confirm(`${id}번 째 일기를 삭제하시겠습니까?`)) { onDelete(id); // 지울 id를 가지고 onDelete 함수 호출 -> App.js에 id값 전달 } }} > 삭제하기 </button> </div> ); }; export default DiaryItem;
▶️ 여기까지 했다면, 무슨 일기를 삭제할 지, id를 받아옴 -> 실제 웹 페이지에서는 삭제 X. 왜? setData 함수에서 랜더링하는 리스트에 삭제되어야 할 id가 전달되지 않았으므로 data에 전달되는 값은 삭제해야되는 data까지 그대로 전달이 된다.
💡 How? -> step 2. 삭제될 아이템 빼고 랜더링하기
이미 DiaryItem.js에서 지울 id값을 가지고 App.js에 있는 함수를 호출했다. 그러면 여기서 그 지울 id를 제외한 나머지 id를 가지고 newDiaryList 를 만들고 newDiaryList를 setData로 전달하여 새로운 데이터를 다시 랜더링 한다.
- filter 함수 : 주어진 함수의 테스트(함수 구현부)를 통과하는 모든 요소를 모아 새로운 배열로 반환합니다.
// App.js
const onDelete = (targetId) => {
const newDiaryList = data.filter((it) => it.id !== targetId);
setData(newDiaryList);
};
이 함수에서는 it의 id값이 targetId와 다른 id값들만 newDiaryList로 반환되는 것을 확인할 수 있습니다.
🌗 결과
삭제하기 버튼 클릭 ⬇️
삭제하기 완료 ⬇️
댓글남기기