Состояние React-Redux потеряно после обновления
Я действительно новичок в React и Redux, я слежу за курсом Стивена Гридера Advanced React и Redux и выполняю аутентификацию на стороне клиента. У меня уже есть токен, сохраненный в моем локальном хранилище, и, казалось, все работало нормально, пока я не обновил страницу. Когда я вхожу/регистрируюсь, навигация изменяется, чтобы отобразить кнопку выхода из системы, но затем, если я вручную обновляю страницу, навигация переключается обратно, чтобы отображать кнопки входа/регистрации.
Я действительно новичок в этом и понятия не имею, что я должен включить в качестве фрагментов кода. Я оставлю редуктор и action/index.js. Также это похоже на мой репозиторий 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;
}
Заранее спасибо, если вам нужен дополнительный фрагмент кода, пожалуйста, дайте мне знать.
Ответы
Ответ 1
Чтобы сохранить состояние Redux через обновление страницы, вам необходимо сохранить состояние приложения, сохранив его в localStorage
и получить его при загрузке страницы. Попробуйте отправить действие в componentDidMount
localStorage
componentDidMount
вашего App
, которое извлекает данные из localStorage
Ответ 2
Вам нужно сохранить состояние приложения в localStorage. Вот урок, сделанный Дэн Абрамовым, создателем редукса.
Ответ 3
В редукционном файле редуктора /auth_reducer.js вы можете определить начальное состояние редуктора.
const initialState = {
user: localStorage.getItem('user'), foo:'bar',
};
export default function(state = initialState, action) {
...
в вашем начальном состоянии вы можете загружать материал из localstorage или из файла cookie (cookie предпочтительнее для файлов auth).
initialState также может быть настроен в вашем createStore. Это вам. Где вам нужно исходное состояние. Я использую async для своих маршрутов, поэтому я не могу использовать createStore для хранения всего моего начального состояния, поскольку некоторые маршруты, возможно, никогда не будут загружены.
const initialState = {
user: localStorage.getItem('user'),
};
const store = createStore(mainReducer, initialState);
Существует библиотека, которую вы можете использовать с именем redux-persist. Это даст вам больше контроля над тем, какое состояние вы хотите сохранить. (https://github.com/rt2zz/redux-persist)
Ответ 4
Проблема в методе saveState, который заменяет загруженное состояние, поэтому вы должны сохранить его как-то так:
export const saveState = state => {
try {
const serializedState = JSON.stringify(mergeDeep(loadState(), state));
localStorage.setItem('state', serializedState);
} catch (err) {
// Ignore write errors.
}
};
Ответ 5
не изобретать велосипед
Для сохранения избыточного состояния даже после обновления страницы вы можете использовать
https://www.npmjs.com/package/redux-persist
Это легко реализовать и надежно.