Redux预加载状态正在覆盖我的应用程序状态

时间:2019-02-25 22:42:13

标签: reactjs redux

要创建会话,我将JWToken存储在localStorage中(不是最安全的位置-我知道)。为了允许用户刷新浏览器窗口,我将用户状态保留在redux中:

const getPersistedState = () => {
    try {
      const persistedToken = JSON.parse(localStorage.getItem('token'));
      const persistedTimeStamp = JSON.parse(localStorage.getItem('authTimeStamp'));
      if (persistedToken === null ||
          persistedTimeStamp === null) {
        return undefined
      }
      const persistedState = { user: { auth: {
            token: persistedToken,
            authTimeStamp: persistedTimeStamp,
            authed: true,
          }
        }
      }
      return persistedState
    } catch(e) {
      return {}
    }
}

const persistedState = getPersistedState()
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

const store = createStore(
    rootReducer,
    persistedState,
    composeEnhancers(applyMiddleware(thunk))
)

我的问题是,如果商店得到更新,整个用户状态将被覆盖。因此,我无法在用户reducer上定义INITIAL_STATE对象,因为它会立即被覆盖。

是否有一种方法可以实现可以与现有状态合并的持久状态,这将使我能够定义INITIAL_STATE

1 个答案:

答案 0 :(得分:0)

这并不意味着您添加前缀persist,意味着减速器是处理该前缀的最佳位置。

localStorage交互更多是一个组成部分。

因此,在通过SET_TOKEN成功检索到所有令牌属性之后,请尝试在组件中调度操作localStorage

// Component.js
const getPersistedState = () => {
  try {
    // TODO: get all attributes in local storage
    this.props.setToken(...attributes); // dispatches SET_TOKEN action
  } catch(e) {
    // error
  }
}

componentDidMount() {
  this.getPersistedState(); // retrieve token attributes
}

// Reducer.js
const INITIAL_STATE = {
  user: {
    auth: {
      token: '',
      authTimeStamp: -1,
      authed: false,
    }
  }
};

// User Reducer handles SET_TOKEN action
const user = (state = INITIAL_STATE, action) {
  switch(action.type) {
    case Action.SET_TOKEN:
      const { token, authTimeStamp, authed } = action.payload;
      return {
        ...state,
        auth: {
          token,
          authTimeStamp,
          auth,
        }
      };
    default:
      return state;
  }
}