刷新后 React-Redux 状态丢失

IT技术 javascript reactjs redux
2021-05-16 02:53:41

我真的是 React 和 Redux 的新手,我一直在关注 Stephen Grider 的 Advanced React 和 Redux 课程,我正在做客户端的身份验证。我已经在本地存储中保存了一个令牌,在我刷新页面之前,一切似乎都运行良好。当我登录/注册时,导航会更改为显示注销按钮,但是如果我手动刷新页面,导航会变回显示登录/注册按钮。

我对此很陌生,不知道应该包含什么作为代码片段。我将离开 reducer 和 actions/index.js。另外是我的git仓库一个LIK。

动作/ index.js

import axios from 'axios';
import { browserHistory } from 'react-router';
import { push } from 'react-router-redux';
import { AUTH_USER, UNAUTH_USER, AUTH_ERROR } from './types';

const API_URL = 'http://localhost:3000';

export function signinUser({ username, password }) {
  return function(dispatch) {
    // Submit username/password to the server
    axios
      .post(`${API_URL}/signin`, { username, password })
      .then(response => {
        // If request is good...
        // - Update state o indicate user is authenticated
        dispatch({ type: AUTH_USER });
        // - Save the JWT token to local storage
        localStorage.setItem('token', response.data.token);
        // - Redirect to the route '/feature'
        browserHistory.push('/feature');
      })
      .catch(() => {
        // If request is bad...
        // -Show an error to the user
        dispatch(authError('Bad login info'));
      });
  };
}

export function signupUser({ username, email, password }) {
  return function(dispatch) {
    axios
      .post(`${API_URL}/signup`, { username, email, password })
      .then(response => {
        dispatch({ type: AUTH_USER });
        localStorage.setItem('token', response.data.token);
        browserHistory.push('/feature');
      })
      .catch(response => {
        // TODO
        console.log(response);
        dispatch(authError('There was an error'));
      });
  };
}

export function authError(error) {
  return {
    type: AUTH_ERROR,
    payload: error
  };
}

export function signoutUser() {
  localStorage.removeItem('token');
  return { type: UNAUTH_USER };
}

减速器/auth_reducer.js

import { AUTH_USER, UNAUTH_USER, AUTH_ERROR } from '../actions/types';
export default function(state = {}, action) {
  switch (action.type) {
    case AUTH_USER:
      return { ...state, error: '', authenticated: true };
    case UNAUTH_USER:
      return { ...state, authenticated: false };
    case AUTH_ERROR:
      return { ...state, error: action.payload };
  }

  return state;
}

提前致谢,如果您需要任何额外的代码片段,请告诉我。

4个回答

不要重新发明轮子

即使在页面刷新后也要存储 redux 状态,您可以使用

https://www.npmjs.com/package/redux-persist

它易于实施且稳健。

在您的减速器文件 reducer/auth_reducer.js 中,您可以定义减速器的初始状态。

const initialState = { 
user: localStorage.getItem('user'), foo:'bar',
};

export default function(state = initialState, action) {
    ...

在您的 initialState 中,您可以从 localstorage 或 cookie 加载内容(cookie 是身份验证的首选)。

initialState 也可以在你的 createStore 中设置。由你决定。您需要初始状态的地方。我对我的路由使用 async,所以我不能使用 createStore 来保存我的所有初始状态,因为某些路由可能永远不会被加载。

const initialState = {
  user: localStorage.getItem('user'),
};

const store = createStore(mainReducer, initialState);

您可以使用一个名为 redux-persist 的库。这将使您更好地控制要保持的状态。( https://github.com/rt2zz/redux-persist )

要通过页面刷新保留 Redux 状态,您需要通过存储应用程序状态localStorage并在页面加载时检索它来持久化应用程序状态尝试在componentDidMount您的App组件中分派一个动作,该动作localStorage

您需要在 localStorage 中保留应用程序状态。是 redux 的创建者 Dan Abramov 制作的教程。