javascript - 使用 Redux 和 Saga 将状态持久化到本地存储
问题描述
我正在关注Dan Abramov的教程。但是,我在步骤添加persistedState
到createStore
我的代码是这样的:
const persistedState = loadState();
const store = createStore(
reducers,
composeEnhancers(applyMiddleware(sagaMiddleware))
)
store.subscribe(throttle(() => {
saveState({
authReducer: store.getState().authpage
})
}, 1000));
我怎样才能persistedState
通过createStore
中间件redux-saga
。
我的减速机:
const reducer = combineReducers({
[authpageContext]: authReducer,
[profilepageContext]: profileReducer,
[reportpageContext]: reportReducer,
[learningContext]: learningReducer,
[globalContext]: globalReducer,
})
我的传奇:
export default function* rootSaga() {
yield all([
authPageSaga(),
profilePageSaga(),
learningSaga(),
reportPageSaga()
])
}
更新
得到一些帮助后。我已连接到 sagas,现在我可以将数据保存到其中。但是这一步我很困惑。
loadState
函数向我返回一个对象 localStorage auth
,如下所示:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6Im1lbWJlcjJAZ21haWwuY29tIiwicGFzc3dvcmQiOiIxMjM0NTYiLCJpYXQiOjE1MzEzOTE1NTMsImV4cCI6MTUzMTM5NTE1M30.75vj-YCeJtxuXjOqzisVRkFVMKe7fcpHLByWQ-x_frE",
"user": {
"id": 2,
"email": "member2@gmail.com",
"firstName": "Mr. Pierre",
"lastName": "Schneider",
"avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/stalewine/128.jpg",
"address": "4706 Kessler Turnpike Apt. 800 Rautown Borders",
"phone": "021-292-7337",
"division": "Front End Group 1",
"password": "123456",
"role": "member"
}
接下来我们如何加载该auth
对象并保存initState
到authReducer
authReducer:
const initState = {
token: '',
user: {},
error: false
}
function authReducer(state = initState, action) {
switch (action.type) {
case AUTH_LOGIN_SUCCEEDED:
return {
...state,
user: action.userResponse
}
case AUTH_LOGOUT_SUCCEEDED:
return {
...state,
user: action.userResponse
}
case AUTH_LOGIN_FAILED:
case AUTH_LOGOUT_FAILED:
return {
...state,
error: true,
user: {}
}
default:
return state
}
}
我试过这样做:
const persistedState = loadState();
const store = createStore(
reducers,
persistedState,
composeEnhancers(applyMiddleware(sagaMiddleware))
)
store.subscribe(throttle(() => {
saveState({
access_token: store.getState().authpage.token,
user: store.getState().authpage.user,
})
}, 1000));
但在authReducer
. 它没有返回我预期的状态。
它向我显示了一个错误:
Unexpected keys "access_token", "user" found in previous state received by the reducer. Expected to find one of the known reducer keys instead: "authpage", "profilepage", "flashmessage", "reportpage", "learning", "global". Unexpected keys will be ignored.
我在这里做错了什么?
解决方案
只要loadState
是同步的并且键名相同,您只需将persistedState
其作为第二个参数传递
const store = createStore(
reducers,
persistedState,
composeEnhancers(applyMiddleware(sagaMiddleware))
)
[preloadedState]
(any):初始状态。您可以选择指定它以在通用应用程序中混合来自服务器的状态,或恢复以前序列化的用户会话。如果您使用 combineReducers 生成 reducer,则这必须是一个普通对象,其形状与传递给它的键的形状相同。否则,您可以自由传递您的减速器可以理解的任何内容。
UPD
由于持久值的结构与商店的结构不同,因此您需要persistedState
在将值传递给之前准备好值createStore
const store = createStore(
reducers,
{
[authpageContext]: {
token: persistedState.access_token,
user: persistedState.user
}
},
composeEnhancers(applyMiddleware(sagaMiddleware))
)
或者在持久化状态时简单地使用相同的名称以避免额外的转换。
store.subscribe(throttle(() => {
saveState({
[authpageContext]: store.getState()[authpageContext]
})
}, 1000));
推荐阅读
- c# - 使用TestCaseSource获取带参数的TestCases
- python - VSCode 上的 Jupyter - Jupyter 笔记本无法启动
- ios - Swift - 使用 AVPlayerItemVideoOutput 访问解码帧:不调用 outputMediaDataWillChange
- reactjs - 是什么导致 _reduxForm 未找到,this.context 未定义?
- django - 间歇性失败:Django Rest Framework 身份验证
- javascript - 设置为使用 Javascript 通过覆盖设置 div 的背景图像?
- video - 将视频拆分为帧时的额外帧
- microsoft-graph-api - 如何从 Graph API 读取 Delve 联系信息/个人资料
- python-3.x - HackerRank 设计师门垫
- sqlite - 无法加载 DLL - SQLite3