=> 원래 코드는 button onClick안에 함수가 들어있었는데, 이는 보기 불편하므로
=> 변수만들어서 함수를 저장해둔후, 호출하는 방식으로!
=> 수정하기 버튼을 누르면 표시한 부분이 폼으로 바뀌면서 수정가능하게 바꿀거다!
😎언제나 데이터를 수정하려면? useState!
-> 수정하는 데이터는 item있는곳에서만 데이터 바꾸면 되는거라서, DiaryItem에서 만지면 되는건가?
-> useState로 t/ f 상태 파악해서 -> 수정하게 해두고
=> 수정하기 버튼 누르고 그 값을 기억하고 그걸로 바꾸게
import { useRef, useState } from "react";
const DiaryItem = ({
author,
content,
created_date,
emotion,
id,
onRemove,
onEdit,
}) => {
const [isEdit, setIsEdit] = useState(false);
// 수정중일때는 boolean타입으로 상태를 파악한후, 수정가능하게 만들거다!
const toggleIsEdit = () => setIsEdit(!isEdit);
//toggle => 상태를 반전시킨다는 뜻, 수정폼 열고 닫는용도
const localContentInput = useRef();
//toggle이 호출되면 isEdit가 가지고 있는 상태의 반대 결과값이 나오게!
const [localContent, setLocalContent] = useState(content);
//content로 받아줘야, 원래 들어있던 content가 나옴
/* 수정취소 : 누르면, 원래 있던 내용이 나와야함(만약 사용자가 더 값을 입력해도, contetn만)*/
const handleQuitEdit = () => {
setIsEdit(false); //수정상태에서 나가야하므로
setLocalContent(content);
};
/* 수정완료 : 누르면, 부모에게서 받아온 데이터 가지고 그 값을 content에 넣게*/
const handleEdit = () => {
//5글자 안넘으면 focus 들어가게!(useRef)
if (localContent.length < 5) {
localContentInput.current.focus();
return;
}
if (window.confirm(`${id}번째 일기를 수정하시겠습니까?`)) {
onEdit(id, localContent);
toggleIsEdit(); //닫아주기
}
};
const handleRemove = () => {
if (window.confirm(`${id}번째 일기를 정말 삭제하시겠습니까?`)) {
onRemove(id); //prop으로 DiaryItem에게 전달했으니까, 사용가능~
}
};
return (
<div className="DiaryItem">
<div className="info">
<span>
작성자: {author} | 감정점수 : {emotion}
</span>
<br />
<span className="date">{new Date(created_date).toLocaleString()}</span>
{/* ms로 저장했던 date를 .toLocaleString()이용해서 한국시간으로 바꿔준다~~ */}
</div>
{/* 수정하기 버튼을 누르면, 새로운 폼이 뜨고, 아닐경우 content가 보여야한다. */}
<div className="content">
{isEdit ? (
<>
{/* textarea안에 수정하면 수정한 값이 담기게 해줄것임(localContent) */}
<textarea
value={localContent}
onChange={(e) => setLocalContent(e.target.value)}
ref={localContentInput}
/>
</>
) : (
<>{content}</>
)}
</div>
{isEdit ? (
<>
<button onClick={handleQuitEdit}>수정취소</button>
<button onClick={handleEdit}>수정완료</button>
</>
) : (
<>
<button onClick={handleRemove}>삭제하기</button>
<button onClick={toggleIsEdit}>수정하기</button>
</>
)}
</div>
);
};
export default DiaryItem;
import { useRef, useState } from "react";
import "./App.css";
import DiaryEditor from "./DiaryEditor";
import DiaryList from "./DiaryList";
function App() {
// app -> editor 적용할 데이터
const [data, setData] = useState([]); // 빈 배열, 앞으로 채워넣을것임
const dataId = useRef(0);
// 전달해줄 함수 onCreate
const onCreate = (author, content, emotion) => {
const created_date = new Date().getTime();
const newItem = {
author, // 비구조화 할당맞다, 키랑 이름 맞추면 그대로 들어감
content,
emotion,
created_date,
id: dataId.current,
};
dataId.current += 1; //current에 1 더해줘야함
setData([newItem, ...data]); //setData를써야
};
// 삭제해줄 함수 onRemove , 어떤 아이디를 갖고있는 애를 지우면 됨!
const onRemove = (targetId) => {
console.log(`${targetId}가 삭제되었습니다.`);
const newDiaryList = data.filter((it) => it.id !== targetId); //다른것만 뉴배열에 넣어라~
console.log(newDiaryList); // 기억하기!! setData함수 안쓰면 삭제는 진행 안됨!
setData(newDiaryList);
}; // 얘를 지우려면, DiaryItem에 가서 지워야함(컴포넌트 전달은 부모인 DiaryList에게!)
// 수정해줄 함수 onEdit
const onEdit = (targetId, newContent) => {
//targetId, newContent 받아가지고와서 => 그 아이디 일치하는 애만 바꿔주면됨
//데이터 바꾸려면 ? setData()사용~
//새로운 데이터를 넘겨줘야함!
setData(
data.map(
(it) => (it.id === targetId ? { ...it, content: newContent } : it)
// ...it 들어온 데이터 뿌려주고, content만 새로운 content로!
)
);
};
return (
<div className="App">
<DiaryEditor onCreate={onCreate} />
<DiaryList onRemove={onRemove} diaryList={data} onEdit={onEdit} />
{/* prop으로 전달함!(부모=> 자식컴포넌트로 데이터 전달!) */}
</div>
);
}
export default App;
-> 수정할 함수인 onEdit확인해서 id일치하는지 확인하고 newContent 넘겨받아서 저장하면됨 (map메소드로)