project/main

axios 요청을 redux안에 넣었을 때 발생하는 에러

lap_mu 2023. 3. 24. 21:07

에러

 

원인

redux로 리팩토링하는 과정에서 axios 요청을 redux안에 넣고 싶다라는 생각에 넣어 봤더니 생긴 에러이다.

boardListItemAdd: (
      state,
    ) => {
      const fetchData = async () => {
      	const res = await axios.get(`/boards?page=${isPage}&size=16`);
        const { data, likeList } = res.data;
        const result = data.map((board: BoardDataProps) => {
          return {
            ...board,
            like: likeList.some(
              (el: { boardId: number; boardTitle: string }) =>
                el.boardId === board.boardId
            ),
          };
        });
        state.likeList = likeList;
        if (
          state.listData.length !== 0 &&
          state.listData.filter((el) => el.boardId === data[0].boardId).length ===
            0
        ) {
          state.listData = [...state.listData, ...result];
        } else if (state.listData.length === 0) {
          state.listData = result;
        }
      }
      fetchData();
    }
  • 리듀서는 순수 함수여야한다.
    • 순수 함수란 side effect를 발생시키지 않는 함수를 말한다.
    • side effect란 함수에서 값을 반환하는 것 말고 외부의 상태나 동작이 변경되는 것을 말한다.

출처: https://velog.io/@2pandi/reduxjstoolkit-Cannot-perform-get-on-a-proxy-that-has-been-revoked-%EC%97%90%EB%9F%ACreducer-%EA%B7%9C%EC%B9%99-%EC%A7%80%ED%82%A4%EA%B8%B0

  • 즉, axios 요청이 side effect를 발생시키기 때문에 발생하는 에러이다.

 

해결

axios 요청을 redux의 reducer안에 사용하지 않고 외부에서 사용해 응답으로 받아온 데이터를 reducer로 전달하는 방향으로 수정했다.

// BoardList.tsx
useEffect(() => {
    setIsLoading(true); 
    const fetchData = async () => {
      const res = await axios.get(`/boards?page=${isPage}&size=16`);

      const { data, likeList } = res.data;

      dispatch(boardListItemAdd({ data, likeList })); // reducer로 전달
      setIsLoading(false);
    };
    fetchData();
  }, [isPage, dispatch]);
  
  // BoardListSlice.ts
  boardListItemAdd: (
      state,
      {
        payload: { data, likeList }, // 전달 받은 데이터
      }: PayloadAction<{ data: BoardDataProps[]; likeList: ILikeList[] }>
    ) => {
      const result = data.map((board: BoardDataProps) => {
        return {
          ...board,
          like: likeList.some(
            (el: { boardId: number; boardTitle: string }) =>
              el.boardId === board.boardId
          ),
        };
      });
      state.likeList = likeList;
      if (
        state.listData.length !== 0 &&
        state.listData.filter((el) => el.boardId === data[0].boardId).length ===
          0
      ) {
        state.listData = [...state.listData, ...result];
      } else if (state.listData.length === 0) {
        state.listData = result;
      }
    }