안녕하세요

2주차 유튜브 API(7 - ERROR 처리) - redux state에는 A non-serializable value 값을 못 넣는다. 본문

복습스터디과제

2주차 유튜브 API(7 - ERROR 처리) - redux state에는 A non-serializable value 값을 못 넣는다.

sakuraop 2023. 1. 28. 11:58

redux로 state에 class를 저장하려했다.

const youtubeApiSlice = createSlice({
  name: "youtubeApiSlice",
  initialState: [],
  reducers: {
    setYoutubeApi(state, action) {
      state.push(action.payload);
    },

    getYoutubeApiClass(state) {
      return state;
    },
  },
});

그리고 이를 불러와 메소드를 활용해보려 했으나 에러가 발생했다.

 

A non-serializable value was detected in an action, in the path: `payload`...

관련 내용: https://velog.io/@kingyong9169/Redux-Tool-kit-%EC%B4%9D%EC%A0%95%EB%A6%AC

 

요약하자면 class처럼 직렬화 불가능한 값을 넣을 수 없다는 것이다.

 

Redux에서 상태값은 순수한 자바스크립트 객체여야 합니다.

객체나 배열 같은 복합 데이터 타입도 사용 가능하지만, 그 내부에 있는 값들은 모두 직렬화 가능한 값이어야 합니다.

직렬화 가능한 값이란 JSON.stringify() 함수를 사용해서 문자열로 변환할 수 있는 값이어야 합니다.

 

직렬화(serialization)가 가능한 값은 일반적으로 원시 타입(primitive type), 객체(object), 배열(array) 등입니다.

 이 값들은 모두 JSON.stringify() 함수를 사용해 문자열로 변환할 수 있으므로 직렬화가 가능합니다.

 

반면에 직렬화가 불가능한 값은 함수(function), 정규표현식(RegExp), Date 객체와 같은 객체, 

그리고 Symbol과 같은 일부 원시 타입입니다. 

이 값들은 JSON.stringify() 함수를 사용해 문자열로 변환할 수 없으므로 직렬화가 불가능합니다.

 

만약 상태값에 직렬화할 수 없는 값이 포함되어 있다면,

Redux DevTools나 Redux Logger 같은 라이브러리에서 에러를 발생시키면서 애플리케이션이 동작하지 않게 됩니다.

예를 들어, Date 객체나 Function 객체 같은 것들은 직렬화할 수 없는 값으로,

Redux 상태값에 포함되면 에러를 발생시키게 됩니다.

 

이러한 직렬화 불가능한 값들이 필요한 경우, Redux Toolkit에서 제공하는

createSlice 함수의 extraReducers 옵션을 사용해서 상태값에 직렬화 불가능한 값을 포함할 수 있습니다.

또는 Redux serialize-deserialize 라이브러리를 사용하여 직렬화할 수 없는 값을 포함하는 상태값을 저장하고 복원할 수 있습니다.

 

class를  createSlice 함수의 extraReducers 옵션을 사용해서 등록하여 사용해도 문제는 없습니까?

createSlice 함수의 extraReducers 옵션으로 등록한 리듀서 함수는

직렬화가 불가능한 값인 class를 포함하여 모든 값들을 사용할 수 있습니다.

이 함수들은 Redux의 내부에서 처리되기 때문에 직렬화나 역직렬화와는 직접적인 연관이 없기 때문입니다.

따라서, extraReducers에서 클래스를 사용해도 문제는 없습니다.

 

하지만 extraReducers를 사용하면 코드의 가독성이 떨어지고,

여러 리듀서 사이에서 발생하는 액션의 충돌 등의 문제가 발생할 수 있기 때문에,

 

일반적으로는 createSlice 함수의 reducers 옵션으로만 모든 리듀서 함수를 등록하고,

필요한 경우에만 extraReducers를 사용하는 것이 좋습니다.

 

바람직하지 않은 듯하여 class를 사용하지 않기로 했다.

const generalMostPopularVideos = async (amount) => {
  const params = {
    key: apiKey,
    part: "snippet",
    chart: "mostPopular",
    regionCode: "kr",
    maxResults: amount,
  };

  try {
    const response = await axios.get("/videos", { params });
    console.log(response.data.items);
    return response.data.items;
  } catch (error) {
    console.log("error", error);
  }
};

export { channelRecentVideos, generalMostPopularVideos };

=> 클래스 메서드가 아니라 함수를 모듈화하여 export 해주었다.