이 블로그는 유데미 '한입 크기로 잘라먹는 리액트' 강의를 보고 복습하고자 작성되었습니다!
이미 작성된 일기 데이터의 삭제와 수정 부분을 만들어보겠습니다.
목차
1. 데이터 삭제
1. DiaryItem 리턴에 삭제 버튼 만들기
2. App.js에 onDelete 함수 만들기
const onRemove = (targetId) => {
console.log(`${targetId}가 삭제되었습니다`);
};
일단 콘솔에 출력만 하도록 만들었습니다.
3. 만든 함수를 불러오도록 하기
<DiaryList diaryList={data} onRemove={onRemove} />
먼저 DiaryItem의 부모인 DiaryList에 함수를 전달합니다.
const DiaryList = ({ onRemove, diaryList }) => {};
그리고 DiaryList에서 prop으로 함수를 받아오도록 합니다.
4. DiaryList 컴포넌트의 리턴 태그 속 DiaryItem에 onRemove 넣어주기
<DiaryItem key={it.id} {...it} onDelete={onRemove} />
5. DiaryItem 컴포넌트에서 함수 받아오기
const DiaryItem = ({
onRemove,
id,
author,
contents,
emotion,
created_date,
}) => {
6. confirm 메세지와 함께 사용하기
<button
onClick={() => {
console.log(id);
if (window.confirm(`${id}번째 일기를 정말 삭제하시겠습니까?`)) {
onRemove(id);
}
}}>
삭제
</button>
사용자가 confirm메세지에 확인을 누르게 되면, 중괄호 부분이 실행됩니다.
7. 6의 버튼 코드 간소화하기
6번 코드를 보면 html 태그 하나가 불필요하게 긴 것을 확인할 수 있습니다.
이것을 함수로 따로 빼서 처리하겠습니다.
const handleRemove = () => {
if (window.confirm(`${id}번째 일기를 정말 삭제하시겠습니까?`)) {
onRemove(id);
}
};
confirm과 onRemove를 처리하는 함수를 만들었습니다.
<button onClick={handleRemove}>삭제</button>
그러면 이렇게 리턴부분에 함수 하나만 써주면 됩니다.
이제 삭제 부분 로직을 실제로 구현하겠습니다.
삭제 로직은 대략적으로 다음과 같습니다.
1. 삭제할 id의 항목만 지운 배열 생성
새 배열을 만들 때는 filter() 함수를 사용해, 함수 인자로 받은 id와 다른 것만 남길 것입니다.
2. setData 함수에 1의 배열을 전달
3. setData함수가 data 배열 바꿈
이것을 코드로 작성해보면 다음과 같습니다.
const onDelete = (targetId) => {
console.log(`${targetId}가 삭제되었습니다`);
const newDiaryList = data.filter((it) => {
it.id !== targetId;
});
setData(newDiaryList);
};
이렇게 삭제 기능 구현이 끝났습니다. 다음은 수정 기능입니다.
2. 데이터 수정
state를 사용해 일기 수정 폼을 만들겠습니다.
1. DiaryItem에서 수정중인지 나타내는 state 만들기
const [isEdit, setisEdit] = useState(false);
2. isEdit 상태를 true->false로, false->true로 바꾸는 함수 만들기
const toggleIsEdit = () => setIsEdit(!isEdit);
참과 거짓처럼 두 가지 상태만을 가지는 것을 토글이라고 합니다.
수정중인지 아닌지 두가지 상태로 정의되기 때문에 toggle로 함수의 이름을 지었습니다.
3. isEdit 값에 따라 일기 내용에 textarea 띄우기
<div className='contents'>
{isEdit ? <textarea></textarea> : <>{contents}</>}
</div>
4. textarea 관리할 state 만들기
const [localContents, setLocalContents] = useState(contents);
state를 바꿀 때 원래 contents에서 수정할 것이므로,
useState() 함수 속 default state를 contents로 설정하였습니다.
5. contents 리턴부분 고치기
<div className='contents'>
{isEdit ? (
<textarea
value={localContents}
onChange={(e) => {
setLocalContents(e.target.value);
}}></textarea>
) : (
<>{contents}</>
)}
</div>
6. 수정중일 때 버튼들도 바뀌도록 리턴에 삼항연산자로 버튼 넣기
<div className='contents'>
{isEdit ? (
<textarea
value={localContents}
onChange={(e) => {
setLocalContents(e.target.value);
}}></textarea>
) : (
<>{contents}</>
)}
{isEdit ? (
<>
<button onClick={toggleIsEdit}>수정 취소</button>
<button>수정 완료</button>
</>
) : (
<>
<button onClick={handleRemove}>삭제</button>
<button onClick={toggleIsEdit}>수정</button>
</>
)}
</div>
그런데 여기서 문제가 생깁니다.
수정하기를 눌러놓고 수정 취소 버튼을 누르면, localContents에서 불러오는 것이라서 취소 전 써놓은 내용이 그대로 나옵니다.
그래서 수정취소 시 쓸 초기화 함수를 만들어 적용해야 합니다.
7. 수정 취소 함수 만들기
const handleQuitEdit = () => {
setIsEdit(false);
setLocalContents(contents);
}
// 리턴 부분
<button onClick={handleQuitEdit}>수정 취소</button>
리턴에서 적용하는 부분도 바꿔줍니다.
이제 수정 로직이 들어가는 핵심 함수를 만들어봅시다.
데이터는 항상 위에서 아래로 가도록 했으니, 함수는 App.js에서 만들고, 이걸 DiaryItem으로 내려보내야 합니다.
8. App.js에서 onEdit 함수 만들기
const onEdit = (targetId, newContents) => {
setData(
data.map((it) =>
it.id === targetId ? { ...it, contents: newContents } : it,
),
);
};
수정 적용을 누른 아이템의 id와 내용을 받아서, 해당 아이템만 수정되도록 할 것입니다.
원래 데이터들과 map 함수로 id를 비교해 원하는 id의 아이템을 찾아 컨텐츠를 수정합니다.
9. 함수 적용
<DiaryList diaryList={data} onRemove={onRemove} onEdit={onEdit} />
const DiaryList = ({ onRemove, diaryList, onEdit }) => {}
<DiaryItem key={it.id} {...it} onRemove={onRemove} onEdit={onEdit} />
const DiaryItem = ({
onRemove,
onEdit,
id,
author,
contents,
emotion,
created_date,
}) => {}
<button onClick={handleEdit}>수정 완료</button>
diaryList와 diaryItem에 onEdit을 넣어줍니다.
handleEdit 함수는 바로 뒤에서 만들 것입니다.
10. handleEdit 함수 만들기
const handleEdit = () => {
if (localContents.length < 5) {
// focus
localContentsInput.current.focus();
return;
}
if (window.confirm(`${id}번째 일기를 수정하시겠습니까?`)) {
onEdit(id, localContents);
toggleIsEdit();
}
};
로컬컨텐츠의 길이를 확인하고, 컨펌 메세지를 띄운 후, 토글까지 바꿔줍니다.
'Udemy' 카테고리의 다른 글
[React] 일기장 프로젝트 0. 페이지 라우팅 (0) | 2023.04.24 |
---|---|
[React] 리액트 생애주기와 useEffect (0) | 2023.04.17 |
[React] 데이터 추가 기능 (0) | 2023.04.16 |
[React] React에서 DOM 조작, 데이터 조회 기능 (리스트 렌더링) (0) | 2023.04.15 |
[React] 리액트로 프로젝트 만들기 (0) | 2023.04.15 |