fetch 함수를 통해 데이터를 가져와 extraReducers를 통해 데이터를 처리했을 때 payload에 데이터가 잘 넘어왔음에도 selector를 통해 데이터를 확인 할 수 없었다.
// postsAsyncThunk.ts
export const fetchPostById = createAsyncThunk<PostDataType, FetchPostByIdArgsType>(
"posts/fetchPostById",
async ({ postId, config }) => {
const { data } = await axios.get(`${process.env.REACT_APP_POST_API_URL}/${postId}`, config);
if (!data) {
throw new Error("Network response was not ok, couldn't find post by id");
}
return data;
}
);
// postsSlice.ts
builder
.addCase(fetchPostById.fulfilled, (state, action: PayloadAction<PostDataType>) => {
state.currentPost = { ...action.payload }
state.status = "succeeded";
})
// postDetailContainer.ts
const post = useSelector(selectCurrentPost);
console.log(post) // 결과값 : {}
fetch 함수 확인, BE 코드 확인, slice에서의 pending/fulfilled/rejected 상황별 디버깅, 초기값 등 모든 경우의 수를 확인해보았으나 문제점이 있는 코드는 없었다.
심지어 payload에는 값이 제대로 담겨오기까지 하니 정신이 나갈 것만 같았다.
Redux Devtools에서도 확인해보니 dispatch와 action, payload까지 모두 문제가 없었다.
오직 useSelector를 통해 데이터를 가져오려고 시도하면 텅 빈 객체가 들어오고 있었다.
그러다가 문득 내가 간과한 점을 깨달았다.
어처구니 없게도 문제가 된 부분은 초기값이었다.
기존의 코드가 비효율적인 부분이 존재하여 개선하는 과정에서 초기값을 건드렸는데 이 부분이 old data에는 반영이 되지 않아서 발생한 문제였다.
---old code---
const initialState: PostsStateType = {
entities: [],
status: "idle",
error: null,
};
---new code---
const initialState: PostsStateType = {
entities: [],
currentPost: null,
status: "idle",
error: null,
};
개선 과정에서 entities에 담겨있는 모든 게시글을 조회해 특정 데이터를 뽑아오기 보다는 currentPost에 특정 게시글만을 담아 필요할 때 보여주는 방식으로 코드 개선 방향을 잡아서 일어난 헤프닝이었다.
새로운 게시글을 작성한 뒤에 디버깅을 실행해보니 문제없이 데이터가 잘 넘어왔다.
const post = useSelector(selectCurrentPost);
console.log(post) => 빈 객체만 넘어왔으나 새로운 게시글을 통해 확인한 결과 아래와 같이 제대로 넘어옴.
데이터 구조가 바뀐다면 반드시 기존의 데이터와 새로운 데이터간의 비교가 필요하다는 것을 깨달았다.
또한 처음부터 '구조를 잘 짜는 것'이 얼마나 중요한지도 배웠다. 만약 처음부터 내 데이터의 구조가 잘 짜여져 있었다면 이런 어처구니 없는 실수 또한 없었을 것이다.
한 차례의 소동이 끝나고 난 뒤 고작 이 문제 하나 때문에 1시간이 넘는 시간을 한숨쉬면서 고민한 내 자신이 밉다.
또 한 편으로는 이런 실수를 지금 겪어봐서 다행인 것 같다. 실무에서 이랬다면 등이 땀으로 축축하게 젖었을 것이다.