<aside> 💡 세부 목표
배열을 이용한 React의 List에 아이템을 동적으로 수정 해보기 With 조건부 렌더링
</aside>
App.js
map을 이용해 해당 id와 data에 들어있는 item 리스트를 순회해 비교해서 같은 경우 새로운 content를 업데이트 시킨다.
import { useRef, useState } from 'react';
import './App.css';
import DiaryEditor from './DiaryEditor';
import DiaryList from './DiaryList';
function App() {
const [data,setData] = useState([]);
const dataId = useRef(0);
const onCreate = (author, content, emotion) => {
const created_date = new Date().getTime();
const newItem = {
author,
content,
emotion,
created_date,
id : dataId.current
}
console.log("newItem : ", newItem);
dataId.current += 1;
setData([newItem, ...data,]) //원래 데이터 를 가져오고 새로운 item은 최상단에 나오도록 함
}
const onDelete = (targetId)=>{
console.log(`${targetId}가 삭제되었습니다.`);
// filter 이용해서 삭제할 Id에 대한 일기 빼고 해당 객체 리스트 가져옴
const newDiaryList = data.filter((it) => it.id !== targetId);
setData(newDiaryList);
};
const onEdit = (targetId, newContent) => {
setData(
data.map((it)=>
it.id === targetId ? {...it, content:newContent} : it
)
)
}
return (
<div className="App">
<DiaryEditor onCreate={onCreate}/>
<DiaryList onEdit={onEdit} onDelete={onDelete} diaryList={data}/>
</div>
);
}
export default App;
DiaryList.js
import DiaryItem from "./DiaryItem";
const DiaryList = ({ onEdit, onDelete, diaryList }) => {
return (
<div className="DiaryList">
<h2>일기 리스트</h2>
<h4>{diaryList.length}개의 일기가 있습니다.</h4>
<div>
{diaryList.map((it, idx) => (
<DiaryItem key={it.id} {...it} onDelete={onDelete} onEdit={onEdit}/>
))}
</div>
</div>
);
};
DiaryList.defaultProps = {
diaryList: [],
}
export default DiaryList;
DiaryItem.js
import { useRef, useState } from 'react';
const DiaryItem = ({ onEdit, onDelete, author, content, created_date, emotion, id }) => {
const [isEdit, setIsEdit] = useState(false); // 현재 수정중인지 수정중이 아닌지 확인용
const toggleIsEdit = () => setIsEdit(!isEdit); // true, false를 toggle 시키기
const [localContent, setLocalContent] = useState(content);
const localContentInput = useRef();
const handleRemove = ()=>{
if(window.confirm(`${id}번째 일기를 정말 삭제하시겠습니까?`)){
onDelete(id);
}
}
const handleQuitEdit = () =>{
setIsEdit(false);
setLocalContent(content);
};
const handleEdit = () => {
if(localContent.length < 5){
localContentInput.current.focus();
return;
}
if(window.confirm(`${id}번 째 일기를 수정하시겠습니까?`)){
onEdit(id,localContent)
toggleIsEdit();
}
}
return <div className="DiaryItem">
<div className="info">
<span>
작성자 : {author} | 감정점수 : {emotion}
</span>
<br />
<span className="date">{new Date(created_date).toLocaleDateString()}</span>
</div>
<div className="content">
{isEdit ? (
<>
<textarea ref={localContentInput}
value={localContent} onChange={(e)=>setLocalContent(e.target.value)}>
</textarea>
</>
):(
<>{content}</>
)}
</div>
{isEdit ? (
<>
<button onClick={handleQuitEdit}>수정 취소</button>
<button onClick={handleEdit}>수정 완료</button>
</>
):(
<>
<button onClick={handleRemove}>삭제하기</button>
<button onClick={toggleIsEdit}>수정하기</button>
</>
)}
</div>
};
export default DiaryItem;