지금부터는 redux-persist
에서의 데이터 저장 및 복원 과정에 대해서 살펴보도록 하겠습니다.
먼저 데이터 저장 과정입니다.
저장 과정은 데이터를 지속시킨다는 의미에서 Persist라고 표현을 합니다.
그리고 데이터를 저장하기 위해서는 Serialize라는 작업을 수행해야 합니다.
Serialize는 우리 말로 하면 직렬화라고 표현합니다.
복잡한 구조의 데이터를 일렬로 쭉 늘어놓는 것을 의미한다고 보면 됩니다.
그렇다면 왜 이런 직렬화를 해야할까요?
그 이유는 바로, Key/Value Storage에서는 값으로 문자열만 넣을 수 있기 때문입니다.
하지만 우리가 저장하려는 Redux의 데이터들은 JavaScript 객체형태로 구성되어 있습니다.
그래서 객체 형태를 그대로 저장할 수 없기 때문에, 이처럼 Serialize 과정을 통해 Storage에 저장할 수 있는 문자열로 변환을 하는 것입니다.
우리가 평소에 종종 사용하는 Serialize의 예로는 JSON.stringify()
함수를 들 수 있습니다.JSON.stringify()
함수는 JavaScript 객체를 직렬화된 문자열로 변환해주는 함수입니다.
예를 들어 아래와 같은 JavaScript 객체를 직렬화 하게 되면,
const data = {
post: [
{ id: 1, title: '첫 번째 게시글입니다.', content: '처음 만난 리덕스 공부 화이팅!' },
{ id: 2, title: '두 번째 게시글입니다.', content: '리덕스 너무 재밌어요~!' },
],
comment: {
1: [
{ id: 1, comment: '화이팅!' },
{ id: 2, comment: '열심히 공부할게요~' },
],
2: [
{ id: 3, comment: '저도 너무 재미있어요ㅎㅎ' },
]
}
}
아래와 같은 직렬화된 문자열이 나오게 됩니다.
'{"post":[{"id":1,"title":"첫 번째 게시글입니다.","content":"처음 만난 리덕스 공부 화이팅!"},{"id":2,"title":"두 번째 게시글입니다.","content":"리덕스 너무 재밌어요~!"}],"comment":{"1":[{"id":1,"comment":"화이팅!"},{"id":2,"comment":"열심히 공부할게요~"}],"2":[{"id":3,"comment":"저도 너무 재미있어요ㅎㅎ"}]}}'
그리고 이 과정을 그림으로 나타내면 아래와 같습니다.
위 그림에서 볼 수 있듯이, 위쪽 그림에 있는 객체 데이터를 JSON.stringify()
함수를 사용해서 Serialize하면 아래쪽에 있는 그림과 같이 직렬화 된 문자열이 나오게됩니다.
redux-persist
에서도 이러한 과정으로 Serialize를 해서 데이터를 저장한다고 보면 됩니다.
다음은 데이터 복원 과정입니다.
복원 과정은 Hydrate라고 표현을 하는데, Hydrate라는 단어는 한자 물 수자를 써서 수화시키다라는 의미를 갖고 있습니다.
쉽게 이해하기 위해서는 마른 곳에 수분을 공급해서 촉촉하게 만든다라는 의미로 이해하면 좋습니다.
그리고 Redux의 관점에서 Hydrate는 비어 있는 Redux Store에 데이터를 공급해서 꽉 채운다는 의미라고 볼 수 있습니다.
결국 데이터를 복원한다는 의미인 것이죠.
Re + Hydrate = Rehydrate
그리고 hydrate 앞에 ‘다시’라는 의미를 갖고 있는 접두사 Re를 붙이면 Rehydrate가 되는데, Rehydrate는 Redux Store의 데이터를 다시 복원시키는 것을 의미합니다.
데이터를 복원하기 위해서는 앞에서 Serialize 시킨 데이터를 다시 원래의 형태로 복원해야 합니다.
그리고 이러한 과정을 Deserialize라고 부르고, 우리 말로는 반대로 직렬화 한다는 의미에서 역직렬화라고 표현합니다.
우리가 평소에 사용하는 Deserialize의 예로는 JSON.parse()
함수를 들 수 있습니다.JSON.parse()
함수는 직렬화된 문자열을 JavaScript 객체로 변환해주는 함수입니다.
위 그림에서 볼 수 있듯이, 위쪽 그림에 있는 Serialize 된 문자열을 JSON.parse()
함수를 사용해서 Deserialize하면, 아래쪽에 있는 그림과 같이 Serialize하기 이전의 JavaScript 객체가 나오게됩니다.
그리고 이렇게 복원한 JavaScript 객체를 Redux Store에 채워넣는 과정이 바로 Hydration입니다.
참고로 컴퓨터 프로그래밍에서 Serialize, Deserialize와 비슷한 의미로 사용되는 단어로, Marshalling과 Unmarshalling이 있습니다.
Marshalling은 데이터를 Storage에 저장하기 위한 형태로 변형하는 것을 의미하고, Unmarshalling은 그 반대로 Marshalling된 데이터를 원래의 형태로 복원하는 것을 의미합니다.
이 단어는 나중에 혹시 개발을 하다보면 등장할 수 있으니, 참고로 알고 계시면 좋을 것 같습니다.
자, 지금까지 배운 데이터 저장 및 복원 과정을 Redux의 관점에서 하나로 나타내면 아래 그림과 같습니다.
먼저 Storage에 저장하려는 데이터를 JSON.stringify()
등의 함수를 사용하여 Serialize 합니다.
이 과정은 Redux Store의 State를 Storage에 저장하는 Persist 과정이죠.
그리고 데이터를 복원하기 위해서는 JSON.parse()
등의 함수를 사용해서 Deserialize 하고, 이렇게 Deserialize 된 데이터를 다시 Redux Store에 채워넣습니다.
이 과정은 Redux Store의 State를 Storage로부터 복원하는 Hydrate 과정입니다.
그리고 redux-persist
에서도 이러한 과정을 통해서 데이터를 저장하고 복원시켜준다고 이해하면 됩니다.
특별히 redux-persist
에서는 데이터를 Serialize, Deserialize하는 과정을, 변환한다는 의미에서 Transform이라고 부릅니다.
그리고 Transform을 수행하는 과정을 별도의 플러그인으로 자유롭게 적용해서 사용할 수 있는 구조를 갖고 있습니다.
위 화면은 redux-persist
의 다양한 Transform 목록을 나타낸 것입니다.
이처럼 다양한 형태의 Transform 중에서 원하는 것을 적용해서 사용할 수 있습니다.
import { persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import { encryptTransform } from 'redux-persist-transform-encrypt';
import rootReducer from './reducers';
const persistConfig = {
key: 'root',
storage: storage,
transforms: [encryptTransform]
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
const store = createStore(persistedReducer);
export default store;
위 코드는 데이터를 암호화해서 저장할 수 있게 해주는 Encrypt Transform을 redux-persist
에 적용하는 예시 코드입니다.
이 코드처럼 encryptTransform
을 import
해서, persistConfig
에 transforms
옵션의 배열 안에 넣어주기만 하면 됩니다.
그러면 Storage에 저장되는 데이터들이 암호화 되어 저장됩니다.
굉장히 간편하게 Transform을 적용할 수 있죠?
그리고 직접 커스텀 Transform을 만들어서 적용할 수도 있는데, 그 부분은 여기서는 따로 다루지 않도록 하겠습니다.
Transforms에 대해 더 자세한 내용이 궁금한 분들은, 아래 링크에 들어가면 관련 내용을 살펴볼 수 있으니 참고하기 바랍니다.
마지막 업데이트: 2023년 07월 14일 00시 00분
이 문서의 저작권은 이인제(소플)에 있습니다. 무단 전재와 무단 복제를 금합니다.