새로 고침 시 Redux 상태 트리를 유지하려면 어떻게 해야 합니까?
Redux 문서의 첫 번째 원칙은 다음과 같습니다.
전체 응용 프로그램 상태는 단일 저장소 내의 개체 트리에 저장됩니다.
그리고 저는 사실 모든 원리를 잘 이해한다고 생각했어요.그런데 지금 어플리케이션이 무슨 뜻인지 헷갈려요.
앱이 웹사이트의 작은 복잡한 부분 중 하나일 뿐이고, 한 페이지 안에만 작동한다면 이해할 수 있습니다.하지만 어플리케이션이 웹사이트 전체를 의미한다면?상태 트리를 유지하려면 LocalStorage 또는 쿠키 등을 사용해야 합니까?하지만 브라우저가 LocalStorage를 지원하지 않으면 어떻게 됩니까?
개발자가 상태 트리를 어떻게 유지하는지 알고 싶습니다. :)
브라우저 새로 고침 후에도 redux 상태를 유지하려면 redux 미들웨어를 사용하는 것이 가장 좋습니다.Redux-persist 및 Redux-스토리지 미들웨어를 확인하십시오.둘 다 원하는 대로 저장 및 로드할 수 있도록 redex 상태를 저장하는 동일한 작업을 수행하려고 합니다.
--
편집
이 질문을 다시 한 지 꽤 되었지만, 다른 질문(더 높은 답변에도 불구하고)이 독자적으로 해결책을 제시하도록 격려하는 것을 보고, 다시 한 번 대답해야겠다고 생각했습니다.
이 편집 시점에서는 두 라이브러리 모두 지난 6개월 이내에 업데이트되었습니다.저희 팀은 몇 년 전부터 레독스 퍼시스턴트를 생산에 사용하고 있으며 아무런 문제가 없었습니다.
간단한 문제처럼 보일 수도 있지만 자체 솔루션을 도입하면 유지보수의 부담이 가중될 뿐만 아니라 버그와 성능 문제가 발생한다는 것을 금방 알게 될 것입니다.가장 먼저 떠오르는 예는 다음과 같습니다.
JSON.stringify★★★★★★★★★★★★★★★★★」JSON.parse불필요한 경우 퍼포먼스가 저하될 수 있을 뿐만 아니라 redux 스토어 등의 중요한 코드로 처리하지 않으면 어플리케이션이 크래시 될 수 있습니다.- (아래 답변에서 일부 언급):앱 상태를 저장 및 복원하는 시기와 방법을 파악하는 것은 간단한 문제가 아닙니다.너무 자주 하면 성능이 저하됩니다.충분하지 않거나 잘못된 상태가 지속되면 더 많은 버그가 발생할 수 있습니다.위에서 언급한 라이브러리는 접근법에 대해 전투 테스트를 거쳤으며, 동작을 커스터마이즈할 수 있는 꽤 확실한 방법을 제공합니다.
- 리덕스(특히 React 에코시스템)의 장점 중 하나는 여러 환경에 배치할 수 있다는 것입니다.이 편집 시점 현재 redux-persist에는 웹용 localForage 라이브러리와 React Native, Electron 및 Node 지원을 포함하여 15개의 스토리지 구현이 있습니다.
요약하자면, 3kB의 최소 + gzipped(이 편집 시점)에 대해서는 저희 팀에게 직접 해결하도록 요청하고 싶지 않습니다.
2019년 8월 25일 편집
댓글에 써있는 대로.원래 redux 스토리지 패키지가 react-stack으로 이동되었습니다.이 접근법은 여전히 자체 상태 관리 솔루션 구현에 중점을 두고 있습니다.
원답
제공된 답변은 어느 시점에서는 유효하지만, 원래의 redux-storage 패키지가 폐지되어 더 이상 유지보수가 되지 않는다는 점에 유의하십시오.
패키지 redux-storage의 원래 제작자는 프로젝트를 폐지하기로 결정하여 더 이상 유지보수를 하지 않습니다.
향후 이러한 문제를 피하기 위해 다른 패키지에 의존하지 않으려면 자체 솔루션을 구축하는 것이 매우 쉽습니다.
필요한 것은 다음과 같습니다.
1- 상태를 반환하는 함수를 만듭니다.localStorage그 다음 주(州)를 넘기고createStore저장소의 수분을 공급하기 위한 두 번째 파라미터의 sredex 함수
const store = createStore(appReducers, state);
2-상태변화를듣고상태가변경될 때마다 상태를 저장합니다.localStorage
store.subscribe(() => {
//this is just a function that saves state to localStorage
saveState(store.getState());
});
그리고 그게 다야...저는 실제로 비슷한 것을 사용하고 있습니다만, 기능을 사용하는 대신 다음과 같이 매우 간단한 수업을 작성했습니다.
class StateLoader {
loadState() {
try {
let serializedState = localStorage.getItem("http://contoso.com:state");
if (serializedState === null) {
return this.initializeState();
}
return JSON.parse(serializedState);
}
catch (err) {
return this.initializeState();
}
}
saveState(state) {
try {
let serializedState = JSON.stringify(state);
localStorage.setItem("http://contoso.com:state", serializedState);
}
catch (err) {
}
}
initializeState() {
return {
//state object
}
};
}
}
그 후 앱을 부트스트랩 할 때...
import StateLoader from "./state.loader"
const stateLoader = new StateLoader();
let store = createStore(appReducers, stateLoader.loadState());
store.subscribe(() => {
stateLoader.saveState(store.getState());
});
도움이 되었으면 좋겠다
퍼포먼스 노트
애플리케이션에서 상태 변경이 매우 빈번한 경우 로컬 스토리지에 너무 자주 저장하면 특히 직렬화/비직렬화할 상태 개체 그래프가 큰 경우 애플리케이션의 성능이 저하될 수 있습니다.이러한 경우 localStorage에 상태를 저장하는 함수를 debounce 또는 throttle로 설정할 수 있습니다.RxJs,lodash뭐 비슷한 거.
이는 Leo의 답변(제3자 립을 사용하지 않고 질문의 목적을 달성하므로 인정된 답변이어야 함)을 기반으로 합니다.
저는 Redux Store를 만들고 로컬 스토리지를 사용하여 유지하며 Getter를 통해 스토어에 쉽게 액세스할 수 있는 Singleton 클래스를 만들었습니다.
이 기능을 사용하려면 메인 클래스 주위에 다음과 같은 Redux-Provider 요소를 배치하십시오.
// ... Your other imports
import PersistedStore from "./PersistedStore";
ReactDOM.render(
<Provider store={PersistedStore.getDefaultStore().store}>
<MainClass />
</Provider>,
document.getElementById('root')
);
프로젝트에 다음 클래스를 추가합니다.
import {
createStore
} from "redux";
import rootReducer from './RootReducer'
const LOCAL_STORAGE_NAME = "localData";
class PersistedStore {
// Singleton property
static DefaultStore = null;
// Accessor to the default instance of this class
static getDefaultStore() {
if (PersistedStore.DefaultStore === null) {
PersistedStore.DefaultStore = new PersistedStore();
}
return PersistedStore.DefaultStore;
}
// Redux store
_store = null;
// When class instance is used, initialize the store
constructor() {
this.initStore()
}
// Initialization of Redux Store
initStore() {
this._store = createStore(rootReducer, PersistedStore.loadState());
this._store.subscribe(() => {
PersistedStore.saveState(this._store.getState());
});
}
// Getter to access the Redux store
get store() {
return this._store;
}
// Loading persisted state from localStorage, no need to access
// this method from the outside
static loadState() {
try {
let serializedState = localStorage.getItem(LOCAL_STORAGE_NAME);
if (serializedState === null) {
return PersistedStore.initialState();
}
return JSON.parse(serializedState);
} catch (err) {
return PersistedStore.initialState();
}
}
// Saving persisted state to localStorage every time something
// changes in the Redux Store (This happens because of the subscribe()
// in the initStore-method). No need to access this method from the outside
static saveState(state) {
try {
let serializedState = JSON.stringify(state);
localStorage.setItem(LOCAL_STORAGE_NAME, serializedState);
} catch (err) {}
}
// Return whatever you want your initial state to be
static initialState() {
return {};
}
}
export default PersistedStore;
언급URL : https://stackoverflow.com/questions/37195590/how-can-i-persist-redux-state-tree-on-refresh
'programing' 카테고리의 다른 글
| 각도 2 카르마 검정 '구성 요소 이름'이(가) 알려진 요소가 아닙니다. (0) | 2023.04.02 |
|---|---|
| 프로젝터 또는 javascript를 사용한 브라우저 뒤로 버튼 (0) | 2023.04.02 |
| 스프링 부트 - @Service 클래스가 다른 @Service 클래스를 호출합니다. (0) | 2023.04.02 |
| 2개의 MVC 구성을 사용한 스프링부트 (0) | 2023.04.02 |
| React setState 콜백을 사용하는 경우 (0) | 2023.04.02 |