刷新后 React-Redux 状态丢失
Posted
技术标签:
【中文标题】刷新后 React-Redux 状态丢失【英文标题】:React-Redux state lost after refresh 【发布时间】:2018-03-22 05:49:08 【问题描述】:我真的是 React 和 Redux 的新手,我一直在学习 Stephen Grider 的高级 React 和 Redux 课程,并且我正在做客户端的身份验证。我已经在本地存储中保存了一个令牌,并且在我刷新页面之前一切似乎都运行良好。当我登录/注册时,导航更改为显示注销按钮,但如果我手动刷新页面,导航更改回显示登录/注册按钮。
我对此真的很陌生,不知道我应该在代码 sn-ps 中包含什么。我将留下 reducer 和 actions/index.js。 this 也是我的 git 存储库的一个赞。
actions/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 ;
reducer/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;
提前致谢,如果您需要任何额外的代码 sn-p 请告诉我。
【问题讨论】:
您是否正在尝试执行localStorage.getItem('token')
并在应用安装后立即登录用户?因为它不会自行发生。
要明确:刷新页面时所有state
都会丢失;您想要保存的任何内容都必须手动保存和恢复。
How can I persist redux state tree on refresh?的可能重复
【参考方案1】:
不要重新发明***
即使在页面刷新后也可以存储 redux 状态,您可以使用
https://www.npmjs.com/package/redux-persist
它易于实现且健壮。
【讨论】:
【参考方案2】:在你的reducer 文件reducer/auth_reducer.js 中你可以定义reducer 的初始状态。
const initialState =
user: localStorage.getItem('user'), foo:'bar',
;
export default function(state = initialState, action)
...
在您的 initialState 中,您可以从 localstorage 或 cookie 加载内容(对于 auth 内容,cookie 是首选)。
initialState 也可以在您的 createStore 中设置。由你决定。你需要初始状态的地方。我对路由使用异步,所以我不能使用 createStore 来保存我的所有初始状态,因为某些路由可能永远不会被加载。
const initialState =
user: localStorage.getItem('user'),
;
const store = createStore(mainReducer, initialState);
您可以使用一个名为 redux-persist 的库。这将使您更好地控制要保留的状态。 (https://github.com/rt2zz/redux-persist)
【讨论】:
【参考方案3】:要通过页面刷新来保留 Redux 状态,您需要通过将其存储在 localStorage
中来持久化应用程序状态并在页面加载时检索它。尝试在App
组件的componentDidMount
中调度一个操作,该操作从localStorage
检索数据
【讨论】:
【参考方案4】:您需要在 localStorage 中保存应用程序状态。 Here 是 redux 的创建者 Dan Abramov 制作的教程。
【讨论】:
@Sergiu Dan Abramov 是 Redux 的创建者,也是 Create React App(而非 React)的合著者。 Jordan Walke 在 Facebook 创建了 React。它在 React 的***上......【参考方案5】:做这样的事情:我在我的项目中使用了这种方法
function saveToLocalStorage(store)
try
const serializedStore = JSON.stringify(store);
window.localStorage.setItem('store', serializedStore);
catch(e)
console.log(e);
function loadFromLocalStorage()
try
const serializedStore = window.localStorage.getItem('store');
if(serializedStore === null) return undefined;
return JSON.parse(serializedStore);
catch(e)
console.log(e);
return undefined;
const persistedState = loadFromLocalStorage();
const store = createStore(reducer, persistedState);
store.subscribe(() => saveToLocalStorage(store.getState()));
【讨论】:
【参考方案6】:我们可以设置 store 来监听 sessionStore 或 localStorage 的值,这样该值就会被保留,
例如
import createStore, applyMiddleware, compose from 'redux';
import routerMiddleware from 'react-router-redux';
import thunk from 'redux-thunk';
import createBrowserHistory as createHistory from 'history';
// import createHistory from 'history/createBrowserHistory';
import rootReducer from '@reducers';
import ApiClient from '@helpers/ApiClient';
import createMiddleware from '@reducers/middleware/clientMiddleware';
export const history = createHistory();
const client = new ApiClient();
const initialState = users: JSON.parse(window.sessionStorage.getItem('redux') || '') ;
const enhancers = [];
const middleware = [
createMiddleware(client),
thunk,
routerMiddleware(history)
];
if (process.env.NODE_ENV === 'development')
const devToolsExtension = window.devToolsExtension;
if (typeof devToolsExtension === 'function')
enhancers.push(devToolsExtension());
const composedEnhancers = compose(
applyMiddleware(...middleware),
...enhancers
);
const store = createStore(
rootReducer,
initialState,
composedEnhancers
);
const storeDataToSessionStorage = () =>
window.sessionStorage.setItem('redux', JSON.stringify(store.getState().users));
;
store.subscribe(storeDataToSessionStorage);
export default store;
这样用户reducer 总是从会话存储中获取初始值。 (也可以根据自己的需求推送到localStorage)
【讨论】:
以上是关于刷新后 React-Redux 状态丢失的主要内容,如果未能解决你的问题,请参考以下文章