브라우저가 새로고침 될 시, 런타임중에 변경된 redux store는 초기화되어 버립니다. 이를 해결하기 위해서 만들어진 유명한 패키지는 redux-persist가 있습니다. 다만 저는 타입스크립트 리액트 앱에서 적용시켰을 때 오류를 겪어서 저장소를 살펴보았더니 해당 저장소는 2019년 이후로는 관리가 되지 않고 있었습니다.
저를 포함한 대부분의 경우 크고 거창한 기능이 필요하기보다는 단순한 데이터 유지 기능만이 필요하므로, 직접 구현하는 것도 좋은 해결책이라고 생각이 들어서 직접 구현해보고자 합니다.
새로고침 시에도 데이터를 잃어버리지 않기 위해서는 저장소를 사용할 필요가 있는데, localStorage나 sessionStorage를 사용할 수 있습니다. 이번에는 sessionStorage를 활용해 보겠습니다.
export class StateManager {
private readonly key = 'ft:state';
public static readonly instance = new StateManager();
setStorage(state: RootState) {
try {
sessionStorage.setItem(this.key, JSON.stringify(state));
} catch (error) {
console.error(error);
}
}
getStorage() {
try {
const data = sessionStorage.getItem(this.key);
if (data) {
return JSON.parse(data);
} else {
return {};
}
} catch (error) {
console.error(error);
}
}
}
정말 간단한 싱글턴 클래스 하나를 만들었는데, 이제 이를 어떻게 리덕스에 연동시킬지 보겠습니다.
Redux Store 객체에는 subscribe함수가 있는데, 액션이 디스패치된 후에 특정한 동작을 하도록 함수를 넘겨줄 수 있습니다.
즉, 이 subscribe에 저장소에 write 함수를 넘겨서 데이터를 유지시킬 수 있습니다. 이렇게 저장소에 저장된 데이터를 createStore할 때 초기값으로 설정한다면 우리가 원하는 대로 새로고침 시에 데이터가 유지될 것입니다.
const store = createStore(
rootReducer,
StateManager.instance.getStorage(),
);
store.subscribe(() => {
StateManager.instance.setStorage(store.getState());
})
createStore의 두 번째 인자 (preloadedState) 로 저장소에 쓰여진 데이터를 줍니다. 이를 초기값으로 사용하고, 앞서 이야기한 subscribe에서 state의 변화를 감지하여 저장소에 데이터를 저장합니다.
'개발 > JS' 카테고리의 다른 글
[Typescript] array, object 를 literal 타입으로 변환하기 (0) | 2021.09.25 |
---|---|
[Typescript] --downlevelIteration 에 대해서 (0) | 2021.08.09 |
[Javascript] var, let, const 의 호이스팅과 스코프 (0) | 2021.05.31 |
Javascript는 call by value일까 call by reference일까? (0) | 2021.05.21 |
댓글