Redux 持久化问题 - 状态未保存在本地

时间:2021-04-04 08:22:00

标签: typescript react-redux redux-saga redux-persist react-typescript

redux-persist 的问题

我正在开发一个 React 打字稿应用程序。我已经实现了 redux-persist 但似乎数据没有保存在 localstorage 中。我的代码如下。尽快回复。

它在开始时正在补水,但不会从本地存储中保存或检索数据。

configureStore.ts

/**
 * Create the store with dynamic reducers
 */

import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';
import { createInjectorsEnhancer } from 'redux-injectors';
import createSagaMiddleware from 'redux-saga';

import { createReducer } from './reducers';
// imports for presist store
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';

// persist config
const persistConfig = {
  key: 'root',
  // blacklist: ['extra'],
  // whitelist: ['auth'],
  // stateReconciler: autoMergeLevel2,
  storage,
}

export function configureAppStore() {
  const reduxSagaMonitorOptions = {};
  const sagaMiddleware = createSagaMiddleware(reduxSagaMonitorOptions);
  const { run: runSaga } = sagaMiddleware;

  // Create the store with saga middleware
  const middlewares = [sagaMiddleware];

  const enhancers = [
    createInjectorsEnhancer({
      createReducer,
      runSaga,
    }),
  ];

  const persistedReducer = persistReducer(persistConfig, createReducer());

  const store = configureStore({
    reducer: persistedReducer,
    middleware: [...getDefaultMiddleware(), ...middlewares],
    devTools: process.env.NODE_ENV !== 'production',
    enhancers,
  });

  const persistor = persistStore(store);

  return {store, persistor};
}

reducers.ts

/**
 * Combine all reducers in this file and export the combined reducers.
 */

import { combineReducers } from '@reduxjs/toolkit';

import { InjectedReducersType } from 'utils/types/injector-typings';

/**
 * Merges the main reducer with the router state and dynamically injected reducers
 */
export function createReducer(injectedReducers: InjectedReducersType = {}) {
  // Initially we don't have any injectedReducers, so returning identity function to avoid the error
  if (Object.keys(injectedReducers).length === 0) {
    return state => state;
  } else {
    return combineReducers({
      ...injectedReducers,
    });
  }
}

切片/index.ts

import { selectAuthLoading } from './selectors';
import { PayloadAction } from '@reduxjs/toolkit';
import { createSlice } from 'utils/@reduxjs/toolkit';
import { useInjectReducer, useInjectSaga } from 'utils/redux-injectors';
import { authSaga } from './saga';
import { AuthState } from './types';

export const initialState: AuthState = {
  isLoggedIn: false,
  token: '',
  user: {
    name: '',
    email: '',
  },
  extras: {
    screenLoading: false,
    authLoading: false,
  },
};

const slice = createSlice({
  name: 'auth',
  initialState,
  reducers: {
    loginUser(
      state,
      action: PayloadAction<{
        email: string;
        password: string;
      }>,
    ) {},
    setLoggedIn(state, action: PayloadAction<boolean>) {
      state.isLoggedIn = action.payload;
    },
    setToken(state, action: PayloadAction<string>) {
      state.token = action.payload;
    },
    setAuthLoading(state, action: PayloadAction<boolean>) {
      state.extras.authLoading = action.payload;
    },
  },
});

export const { actions: authActions } = slice;

export const useAuthSlice = () => {
  useInjectReducer({ key: slice.name, reducer: slice.reducer });
  useInjectSaga({ key: slice.name, saga: authSaga });
  return { actions: slice.actions };
};

index.tsx

/**
 * index.tsx
 *
 * This is the entry file for the application
 */

import 'react-app-polyfill/ie11';
import 'react-app-polyfill/stable';

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Provider } from 'react-redux';

// Use consistent styling
import 'sanitize.css/sanitize.css';

// Import root app
import { App } from 'app';

import { HelmetProvider } from 'react-helmet-async';

import { configureAppStore } from 'store/configureStore';

import reportWebVitals from 'reportWebVitals';

// Redux Persist imports
import { PersistGate } from 'redux-persist/integration/react';

// Initialize languages
import './locales/i18n';
// Components
import { ScreenLoader } from './app/components/ScreenLoader';

const { store, persistor } = configureAppStore();
const MOUNT_NODE = document.getElementById('root') as HTMLElement;

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <PersistGate loading={<ScreenLoader />} persistor={persistor}>
        <HelmetProvider>
          <React.StrictMode>
            <App />
          </React.StrictMode>
        </HelmetProvider>
      </PersistGate>
    </Provider>
  </React.StrictMode>,
  MOUNT_NODE,
);

// Hot reloadable translation json files
if (module.hot) {
  module.hot.accept(['./locales/i18n'], () => {
    // No need to render the App again because i18next works with the hooks
  });
}
reportWebVitals();

saga.ts

import axios from 'axios';
import { take, call, put, select, takeLatest } from 'redux-saga/effects';
import { authActions as actions } from '.';
import { API_URL } from './../../../utils/constants';
import { User } from './../../../API';
import { ToastContainer, toast } from 'react-toastify';

// Logging in the user
// function* loginUserSaga(payload: {email: string, password: string}){
function* loginUserSaga(action: any) {
  try {
    yield put({ type: actions.setAuthLoading.type, payload: true });
    const response = yield call(User.getUser, action.payload);
    if (response && response.data || response.data === '') {
      yield put({ type: actions.setAuthLoading.type, payload: false });
      yield put({type: actions.setToken.type, payload: response.data.data.accessToken});
      toast(response.data.message, {
        type:
          response.data.message.toLowerCase() === 'success'
            ? 'success'
            : 'warning',
      });
    } else {
      yield put({ type: actions.setAuthLoading.type, payload: false });
      toast('Unknown error!', {
        type: 'error',
      });
    }
  } catch (error) {
    yield put({ type: actions.setAuthLoading.type, payload: false });
    toast(error.message, {
      type: 'error',
    });
  }
}
// Setting logged in user
function* setLoggedSaga(payload: any) {
  yield put({ type: actions.setAuthLoading.type, payload: true });
  console.log(payload);
  yield put({ type: actions.setAuthLoading.type, payload: false });
}

export function* authSaga() {
  yield takeLatest(actions.setLoggedIn.type, setLoggedSaga);
  yield takeLatest(actions.loginUser.type, loginUserSaga);
}

0 个答案:

没有答案