수정한 데이터를 다시 홈에 넣는 방법을 고민했다. 현재는 context API도, Redux도 쓰면 안 되는데 어떻게 값을 넘겨줄 수 있을까... detail 페이지로 넘겨준 방식대로 navigate를 사용해 넘겨주면 되지 않을까? 하는 가설을 세웠다. 테스트해본 결과, 잘 넘어가는 것을 알 수 있었다.
// Detail.jsx
navigate(`/`, { state: { deletedExpenses: { deletedExpenses } } });
일단 Detail.jsx에서 필터링을 통해 미리 삭제된 배열을 Home.jsx에 넘기고, 아래 코드처럼 적어주니 삭제가 잘 되었다.
// Home.jsx
useEffect(() => {
if (location.state.deletedExpenses) {
const { updatedDeletedExpenses } = location.state.deletedExpenses;
setExpenses(updatedDeletedExpenses);
}
}, []);
그러나 새로고침을 했을 때 삭제된 그대로라는 문제가 있었다. updatedDeleteExpenses를 초기화해줄 필요가 있을 것 같다는 점을 느끼고는 있었다. (이게 사실 어찌보면 답이었다. 방법을 몰랐을 뿐...)
튜터님께서도 react-router-dom 5버전을 사용해 이 문제를 내셨는데, 6버전을 사용할 때의 방법에 대해서는 어렵게 느낄 수 있다고 하셨다. (다행이다...)
튜터님이 보셨을 때 내가 전에 짠 로직, 그러니까 Datail.jsx에서 삭제할 expense의 id만 Home.jsx에 넘겨주는 방식으로 변경해보았다.
// Home.jsx
useEffect(() => {
if (location.state.deleteExpenseId) {
const { deleteExpenseId } = location.state.deleteExpenseId;
const deletedExpenses = expenses.filter((expense) => {
return deleteExpenseId !== expense.id;
});
setExpenses(deletedExpenses);
location.state.deleteExpenseId = "";
}
}, []);
여기서 두 가지의 문제가 또 발생했다.
결국 튜터님과 오랜 시간 고민하다가, 로직을 다시 STEP2에서 사용한 로직과 유사하게 바꾼 다음 코드 한 줄을 추가해 해결했다.
// Home.jsx
navigate(location.pathname, { state: null, replace: true });
이 코드에 대해 설명을 하자면, navigate를 사용해 다시 현재 페이지로 가는데, state, replace를 사용해 히스토리를 없애주는 것이다. 그러면 새로고침을 했을 때 기존의 expenses 파일들이 다시 나타난다.
아래는 각 파일의 삭제 기능에 해당하는 부분의 코드이다.
// Detail.jsx
const deleteExpenseHandler = (deleteExpenseId) => {
const deletedExpenses = expenses.filter((expense) => {
return deleteExpenseId !== expense.id;
});
return deletedExpenses;
};
const handleDelete = () => {
confirm("정말로 삭제하시겠습니까?");
const deleteExpenseId = expense.id;
const deletedExpenses = deleteExpenseHandler(deleteExpenseId);
navigate(`/`, { state: { deletedExpenses: { deletedExpenses } } });
};
// Home.jsx
useEffect(() => {
if (location.state !== null) {
if (location.state.deletedExpenses) {
const { deletedExpenses } = location.state.deletedExpenses;
setExpenses(deletedExpenses);
navigate(location.pathname, { state: null, replace: true });
}
}
}, []);
(수정 코드는 임의로 삭제했다.)
삭제 기능과 비슷한 점이 많아서 크게 어려운 점은 없었는데, 삭제에서 쓰던 filter()를 그대로 수정에서도 쓰는 바람에 오랫동안 애먹었다. map()을 써야한다는 점은 투두 리스트 때도 배웠던 점인데... 그래서 해당 사실을 깨닫고 기쁨과 허무함의 감정이 동시에 들었다. 아래는 해당 코드가 들어있는 함수이다.
// Detail.jsx
const updateExpenseHandler = (updateExpense) => {
const updatedExpenses = expenses.map((expense) => {
if (updateExpense.id !== expense.id) {
return expense;
} else if (updateExpense.id === expense.id) {
return updateExpense;
}
});
return updatedExpenses;
};
솔님 최고 👏👏👏
저는... 로컬스토리지에 데이터를 저장한 순간부터 뭔가 잘못되어가고 있는 것 같습니다 ^.^
수정 기능이 정말 문제네요 미치겠다.
오늘도 정말 수고 많으셨고 내일도 화이팅입니다 !!