리덕스의 스타일 가이드를 참고하여 보면 직렬화 불가능한 값들을 상태나 액션에 넣지 말라고 명시되어 있다.
직렬화(serialize) 불가능한 값들을 상태나 액션에 넣지 마라.
Promises, Symbols, Maps/Sets, 함수들, 또는 클래스 인스턴스와 같은 직렬화 불가능한 것들을 리덕스 스토어의 상태나 디스패치되는 액션에 넣는 것을 피하라. 이것은 리덕스 개발자 도구로 디버깅하는 것과 같은 기능이 제대로 동작하게 한다. 또한 UI도 예상한 것처럼 업데이트되게 한다.
예외 : 리듀서에 도달하기 전, 액션을 미들웨어가 가로채서 중지시킨다면, 직렬화 불가능한 값들을 액션에 넣을 수 있다. 예를 들어, redux-thunk나 redux-promise같은 것들이 있다.
무슨 말일까?
자바스크립트에서 사용하는 데이터 타입은 주로 객체(object)이다. 하지만 자바스크립트 객체가 다른 언어나 다른 환경에서도 똑같이 사용될 수 있을까? 그렇지 않다. 간단한 예로 localstorage가 존재한다. localstorage는 값으로 string을 가질 수 있지만 object는 가질 수 없다. 이럴때 우리는 json.stringify를 통해 object를 스트링화 하게된다. 이것이 직렬화 과정이다. 다시 꺼내쓸 때는 스트링은 json.parse하여 객체로 다시 변환한다. 이것이 역직렬화이다. 이때 직렬화 전 객체와 역직렬화된 객체는 같아야한다.
위와 같이 보통의 자바스크립트에서 직렬화를 이용하는 방법은 json 객체의 stringify와 parse를 사용하는 것이다.
상태와 액션은 주로 네트워크 통신을 통해 서버와 클라이언트간 주고 받는 경우가 많다. 만약 직렬화가 불가능한 값들이 상태나 액션에 포함되어 있다면, 이를 네트워크로 전송하거나 수신 할 때 문제가 발생할 수 있다. 데이터의 직렬화는 객체를 바이트 스트림(문자 스트림 = stringify)으로 변환하는 과정인데, 직렬화 불가능한 값들은 이 과정에서 오류를 일으킨다.
리덕스는 보통 브라우저의 로컬 스토리지나 세션 스토리지를 이용하여 상태를 저장하고 복원하는 기능을 사용한다. 하지만 직렬화 불가능한 값들이 포함되어 있다면, 이러한 저장 및 복원 과정에서 문제가 발생 할 수 있다.
리덕스의 개발자 도구나 로깅 기능을 통해 상태 변화를 추적하거나 디버깅하는데 문제를 일으킨다. 직렬화 불가능한 값들이 포함되어 있다면, 상태 변화를 모니터링하는 도구나 기능이 제대로 동작하지 않을 수 있다.
리덕스와 함께 사용되는 몇몇 서드파티 라이브러리는 직렬화 가능한 값들을 전제로 동작하는 경우가 많다. 만약 이러한 값들이 리덕스 상태나 액션에 포함되어 있다면, 라이브러리들과의 호환성 문제가 발생할 수 있다.
직렬화 불가능한 값들을 리덕스 상태나 액션에 넣는 것은 좋지않다. 아니, 넣으면 안된다. 만약 직렬화가 필요한 값이라면, 그 값을 직렬화 가능한 형태로 변환하여 사용하는 것이 좋다.