我是React和Redux的新手,我一直在关注Stephen Grider的Advanced React和Redux课程,我正在进行身份验证的客户端。我已经在我的本地存储上保存了一个令牌,所有内容似乎都正常工作,直到我刷新页面。当我登录/注册导航更改以显示注销按钮但是如果我手动刷新页面,导航将更改为显示登录/注册按钮。
我真的很陌生,不知道我应该包含哪些代码片段。我将留下reducer和actions / index.js。另外this对我的git存储库很有用。
动作/ 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;
}
提前致谢,如果您需要任何额外的代码段,请告诉我们。
答案 0 :(得分:5)
要通过页面刷新保留Redux状态,您需要将应用程序状态保存在localStorage
中并在页面加载时检索它。尝试在componentDidMount
组件的App
中发送操作,该组件会从localStorage
答案 1 :(得分:2)
在减速器文件reducer / auth_reducer.js中,您可以定义减速器的初始状态。
const initialState = {
user: localStorage.getItem('user'), foo:'bar',
};
export default function(state = initialState, action) {
...
在您的initialState中,您可以从localstorage或cookie中加载内容(对于身份验证内容,首选cookie)。
initialState也可以在createStore中设置。由你决定。您需要初始状态的地方。我对路由使用了异步,因此由于某些路由可能永远不会加载,因此无法使用createStore保留所有初始状态。
const initialState = {
user: localStorage.getItem('user'),
};
const store = createStore(mainReducer, initialState);
您可以使用一个名为redux-persist的库。这将使您可以更好地控制要保留的状态。 (https://github.com/rt2zz/redux-persist)
答案 2 :(得分:1)
您需要在localStorage中保留应用状态。 Here是由redux的创建者Dan Abramov制作的教程。
答案 3 :(得分:1)
答案 4 :(得分:0)
做这样的事情:我在我的项目中使用了这种方法
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()));
答案 5 :(得分:0)
我们可以设置 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)