javascript - 使用 Redux 和 Saga 将状态保留到本地存储

标签 javascript reactjs redux redux-saga

我正在关注 Dan Abramov 的 the tutorial。但是,我在将 persistedState 添加到 createStore

的步骤中感到困惑

我的代码是这样的:

const persistedState = loadState();

const store = createStore(
  reducers,
  composeEnhancers(applyMiddleware(sagaMiddleware))
)

store.subscribe(throttle(() => {
  saveState({
    authReducer: store.getState().authpage
  })
}, 1000));

如何使用 redux-saga 中间件将 persistedState 传递给 createStore

我的 reducer :

const reducer = combineReducers({
[authpageContext]: authReducer,
  [profilepageContext]: profileReducer,
  [reportpageContext]: reportReducer,
  [learningContext]: learningReducer,
  [globalContext]: globalReducer,
})

我的传奇:

export default function* rootSaga() {
  yield all([
    authPageSaga(),
    profilePageSaga(),
    learningSaga(),
    reportPageSaga()
  ])
}

更新

获得一些帮助后。我已连接到传奇,现在我可以将数据保存到其中。但这一步我很困惑。

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 对象并保存到 authReducer 中的 initState

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中。它没有返回我所期望的状态。

它向我显示了一个错误:

在 reducer 收到的先前状态中发现意外的键“access_token”、“user”。期望找到已知的缩减器键之一:“authpage”、“profilepage”、“flashmessage”、“reportpage”、“learning”、“global”。意外的键将被忽略。

我在这里做错了什么?

最佳答案

假设 loadState 是同步的并且键名称相同,您只需将 persistedState 作为第二个参数传递

const store = createStore(
  reducers,
  persistedState,
  composeEnhancers(applyMiddleware(sagaMiddleware))
)

Docs

  1. [preloadedState] (any): The initial state. You may optionally specify it to hydrate the state from the server in universal apps, or to restore a previously serialized user session. If you produced reducer with combineReducers, this must be a plain object with the same shape as the keys passed to it. Otherwise, you are free to pass anything that your reducer can understand.

UPD 由于持久值的结构与存储的结构不同,因此您需要在将其传递给 createStore 之前准备 persistedState

const store = createStore(
  reducers,
  {
    [authpageContext]: {
      token: persistedState.access_token,
      user: persistedState.user
    }
  },
  composeEnhancers(applyMiddleware(sagaMiddleware))
)

或者在保存状态时简单地使用相同的名称以避免额外的转换。

store.subscribe(throttle(() => {
  saveState({
    [authpageContext]: store.getState()[authpageContext]
  })
}, 1000));

关于javascript - 使用 Redux 和 Saga 将状态保留到本地存储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51360678/

相关文章:

reactjs - React props 不随 redux store 更新

javascript - 如果一个 div 有这两个类,隐藏包装器

javascript - jQuery Load 不解析 HTML 变量

javascript - Formik 和 ReactJs : SetFieldValue from child to parent component

node.js - React-Router 与 Node.js

javascript - 环境变量 react

javascript - 如何调度多个 action creator(React + Redux + 服务端渲染)

javascript - 仅替换字符串末尾的文本

javascript - 如何用span包裹引用的文本?

reactjs - 如何在 React.js 中将图像上传到 Firebase 存储并同时将 URL 上传到 Firestore?