【发布时间】:2016-03-06 10:58:30
【问题描述】:
我有一个多步骤表单应用程序,我正在努力思考如何保存我的 redux 状态并在刷新后重放它?在应用程序中返回/前进按预期工作,但在浏览器刷新后,我之前的状态为空。理想情况下,我希望能够在与路径相关的会话存储中保存先前的状态,以便稍后重播,但我不知道如何轻松做到这一点。有没有人做过这样的事情并且可以提供一些指示?谢谢。
【问题讨论】:
标签: reactjs react-router redux
我有一个多步骤表单应用程序,我正在努力思考如何保存我的 redux 状态并在刷新后重放它?在应用程序中返回/前进按预期工作,但在浏览器刷新后,我之前的状态为空。理想情况下,我希望能够在与路径相关的会话存储中保存先前的状态,以便稍后重播,但我不知道如何轻松做到这一点。有没有人做过这样的事情并且可以提供一些指示?谢谢。
【问题讨论】:
标签: reactjs react-router redux
您似乎正在尝试在多页上下文中使用单页应用程序框架。为了使两者更好地结合在一起,您可以考虑制作自己的中间件来同步与localStorage 之间的状态,以创建一个在刷新/页面导航后似乎没有丢失任何状态的应用。
createStoreWithMiddleware 函数创建的开头(localStorageLoad)和结尾(localStorageDump)插入一个中间件(右之前redux-logger):// store/configureStore.js
const createStoreWithMiddleware = applyMiddleware(
localStorageLoad, thunk, promise, localStorageDump, logger
)(createStore);
// index.js
const store = configureStore();
store.dispatch({ type: 'INIT' });
ReactDOM.render(<App />, document.getElementById('root'));
localStorageLoad 将处理INIT 操作并调度某种SET_STATE 操作,其中将包含具有先前保存在localStorage 中的状态的有效负载。
// middleware/localStorageLoad.js
export default store => next => action => {
const { type } = action;
if (type === 'INIT') {
try {
const storedState = JSON.parse(
localStorage.getItem('YOUR_APP_NAME')
);
if (storedState) {
store.dispatch({
type: 'RESET_STATE',
payload: storedState
});
}
return;
} catch (e) {
// Unable to load or parse stored state, proceed as usual
}
}
next(action);
}
然后,添加一个reducer,用该有效负载替换状态,有效地像以前一样重新启动应用程序。
localStorageDump 中间件,该中间件位于将每个简化状态对象保存到localStorage 的链末尾。像这样:// middleware/localStorageDump.js
export default store => next => action => {
const state = store.getState();
localStorage.setItem('YOUR_APP_NAME', JSON.stringify(state));
next(action);
}
只是一个想法,还没有真正尝试过。希望这有助于您开始寻求解决方案。
【讨论】:
const middleware = applyMiddleware(..., sessionStorageSave);我的 sessionStorageSave:export default store => next => action => { next(action); const state = store.getState(); let newState = {}; for (var key in state) { if( state.hasOwnProperty(key) ) { if (state[key].toJS) { newState[key] = state[key].toJS(); } } } sessionStorage.setItem("key", JSON.stringify(newState)); }
您无法在刷新时存储状态,这是正常的。通常,您将这些存储在 cookie 或网络存储中。
还原:
Form 组件时,使用componentWillMount 方法将localstorage 和dispatch 的数据读取到reducer如果你使用 redux 存储表单数据,则调度 localstorage 的属性。
如果不读取Form组件内部的localstorage并设置初始值。
希望这会有所帮助!
【讨论】:
closed a tab 和revisited 应用程序时的状态。这实际上与路由器转换无关,而是与 redux 存储的内部状态有关。你可能想看看 github.com/erikras/redux-form 这将表单状态保存在 redux 存储中。因此,即使您转换回来,除非您另有说明并传递了正确的道具,否则表单中的状态仍然是相同的。