코드개선 - Redux Tool Kit 포스트 데이터 가져오기

김종현·2024년 7월 1일
0

코드 개선

목록 보기
1/1

코드

---old code---
const PostDetailContainer: React.FC = () => {
//...
  const [post, setPost] = useState<PostDataType | undefined>(undefined);
  const fetchedPost: PostDataType | undefined = useSelector((state: RootState) => selectSinglePostById(state, postId));
  const selectedPost = useMemo(() => fetchedPost, [fetchedPost]);
 useEffect(() => {
    if (selectedPost) {
      setPost(selectedPost);
    }
    if (!fetchedPost) {
      dispatch(fetchPostById({ postId }));
    }
  }, [fetchedPost, postId, dispatch]);

// 이하 생략
}

---new code---
const PostDetailContainer: React.FC = () => {
  //...
  const post = useSelector(selectCurrentPost);
  useEffect(() => {
    if (postId) {
      dispatch(fetchPostById({ postId }));
    }
    if (!post) {
      dispatch(fetchPostById({ postId }));
    }
  }, [postId, post, dispatch]);
// 이하 생략

기존의 코드에선 앱이 실행될 때 index.ts에서 모든 posts를 패치하여 entities에 저장한 것중 필요한 포스트만을 찾아서 가져오는 코드였다.

개선 이유

필요한 특정 데이터를 모든 데이터에서 일일이 찾아서 가져오는 식의 코드는 비효율적이라고 생각했다.

더욱이 'fetchPosts 코드에만 의존하여 데이터를 처리하는 것'은 '의존성' 문제도 있고 '단일 책임 원칙'에도 어긋난다고 생각했다.

그래서 fetchPostById 코드를 추가했다.

개선 방향

---초기값에 currentPost를 추가, 특정 포스트 데이터를 담도록 변경---
const initialState: PostsStateType = {
  entities: [],
  currentPost: null,
  status: "idle",
  error: null,
};
//payload 처리
type RejectErrorType = {
  code: number;
  status: string;
  message: string;
}

builder
  	  .addCase(fetchPostById.pending, (state) => {
        state.status = "loading";
        state.error = null;
      })
      .addCase(fetchPostById.fulfilled, (state, action: PayloadAction<PostDataType>) => {
        state.currentPost = { ...action.payload }
        state.status = "succeeded";
      })
      .addCase(fetchPostById.rejected, (state, action) => {
        state.status = "failed";
        if (action.payload) {
          state.error = (action.payload as RejectErrorType).message || 'failed to fetchPostById';
        } else {
          state.error = action.error.message || 'failed to fetchPostById';
        }
      })
---단일 포스트 패치 함수 추가---
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;
  }
);

느낀점

  1. fetchPosts(모든 포스트 데이터 패치)에 대한 의존도를 없앨 수 있었다.

-기존 초기값에는 entities만 있었으나 currentPost를 추가함으로써 목적에 맞게 데이터를 보관하고 사용할 수 있게 되었기 때문이다.

  1. 데이터 구조를 잘 짜는 것이 정말로! 정말로! 중요하다.

-전체 데이터와 단일 데이터를 불러오는 함수의 분리는 당연히 기초 단계에 해당한다. 그러나 나는 잘못된 구조 설계로 posts에 모든 것을 맡기는 형태로 코드를 짜고 있었다.

-만약 데이터 구조를 제대로 설계했더라면 이런식의 시간 낭비 및 비효율적인 코드 작성을 방지할 수 있었을 것이다.

-지금 이 상황뿐 아니라 나는 Post데이터를 구성할 때 여러번 데이터 구조를 수정하다보니 시간을 많이 소요할 수 밖에 없었다.

  1. 개발은 경험이다.

-이 모든 것이 경험치에 누적되어 있었다면 지금과 같은 실수는 없었을 것이다. 경험을 내 것으로 녹여내는 것이 능숙한 개발로 이어지는 것 같다.

profile
고양이 릴스 매니아

0개의 댓글