// useFetchDiary.js
export const useFetchDiary = () => {
const dispatch = useDispatch();
const diarySlice = useSelector((state) => state.diary);
useEffect(() => {
const fetchTodos = async () => {
const { data } = await axios.get("http://localhost:4000/posts");
const uniqueData = Array.from(new Set([...data, ...diarySlice]));
dispatch(getDiary(uniqueData));
};
fetchTodos();
}, []);
return diarySlice;
};
다이어리 리스트를 보여줄 때 사용하는 useFetchDiaries 커스텀 훅이다. uniqueData를 만든 이유는 리스트를 렌더링 할 때 서버에서가져온거 + 리덕스에 있는거 중복되길래 set을 사용했었다.
그런데 이때는 page를 따로 분리해서 사용하지 않고 바로 기능부터 만들어서 몰랐는데 얘를 페이지로 분리해서 사요하니까 다른 페이지로 이동했다가 다시 이 페이지로 돌아오면 컴포넌트가 렌더링되면서 리덕스에 계쏙해서 똑같은 데이터가 추가되고, 그 데이터가 렌더링 되는거다.
그래서 아래와 같이 수정했다.
export const useFetchDiaries = () => {
const dispatch = useDispatch();
const diarySlice = useSelector((state) => state.diary);
useEffect(() => {
const fetchTodos = async () => {
const { data } = await axios.get("http://localhost:4000/posts");
const uniqueData = data.filter((item) => {
const existingItem = diarySlice.find((diary) => diary.id === item.id);
return !existingItem;
});
const mergedData = [...uniqueData, ...diarySlice];
dispatch(getDiary(mergedData));
};
fetchTodos();
}, []);
return diarySlice;
};
일단 서버에서 받아온 데이터(배열)를 가지고 그 안의 일기 하나를 item이라고 햇을때, 내 리덕스인 diarySlice에서 그 안의 일기 하나인 diary랑 item을 id를 기준으로 비교해서 이미 존재하는 existing item을 찾는다
최종적으로 반환해주는 배열은 그 존재하는 아이템이 없는! 값만 필터링해서 배열로 담아서 uniqueData에 할당한다.
그 다음 필터링한 데이터(기존에 리덕스에 저장되지 않은 새롭게 작성한 서버의 데이터)와 기존 데이터를 전개연산자로 풀어서 배열에 저장한 다음 mergedData에 저장하여 최종적으로 중복이 없지만 업데이트가 반영된 배열을 만든다. 그리고 getDiary 액션 크리에이터로 보내어 리듀서에게 전달한다.
이렇게 하면 페이지간 이동 후에도 컴포넌트가 렌더링될때 중복된 값이 계속해서 추가되지 않는다.