새로 고침 후 React-Redux 상태가 손실됨
저는 React와 Redux를 처음 접하는 사람입니다. Stephen Grider의 Advanced React와 Redux 코스를 따라 클라이언트 측 인증을 수행하고 있습니다.로컬 스토리지에 이미 토큰이 저장되어 있어 페이지를 새로 고칠 때까지 모든 것이 정상적으로 동작하는 것 같았습니다.로그인/로그아웃 버튼을 표시하기 위해 네비게이션 변경을 할 때 수동으로 페이지를 새로 고치면 네비게이션이 다시 로그인/사인업 버튼을 표시하도록 변경됩니다.
저는 이런 것을 처음 접해서 코드 스니펫에 무엇을 넣어야 할지 모르겠어요.리듀서와 actions/index.js는 남겨두겠습니다.그리고 이건 제 git 저장소와 비슷해요.
actions/index.displaces
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_discer.displaces
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;
}
감사합니다, 혹시 코드 스니펫이 더 필요하시면 알려주세요.
수레바퀴를 재창조하지 않다
페이지를 새로 고친 후에도 축소 상태를 저장하려면
https://www.npmjs.com/package/redux-persist
구현이 쉽고 견고합니다.
reducer 파일 reducer/auth_reducer.js에서 reducer의 초기 상태를 정의할 수 있습니다.
const initialState = {
user: localStorage.getItem('user'), foo:'bar',
};
export default function(state = initialState, action) {
...
initialState에서는 로컬 스토리지 또는 쿠키에서 로딩할 수 있습니다(쿠키는 인증용으로 선호됩니다).
initialState는 createStore에서도 설정할 수 있습니다.당신 마음대로 하세요.초기 상태가 필요한 곳.루트에 비동기 기능을 사용하기 때문에 일부 루트는 로드되지 않을 수 있으므로 모든 초기 상태를 유지하기 위해 createStore를 사용할 수 없습니다.
const initialState = {
user: localStorage.getItem('user'),
};
const store = createStore(mainReducer, initialState);
redex-persist라고 하는 라이브러리가 있습니다.이렇게 하면 원하는 상태를 더 잘 제어할 수 있습니다.(https://github.com/rt2zz/redux-persist)
페이지 새로 고침을 통해 Redux 상태를 유지하려면 앱 상태를 다음 위치에 저장하여 유지해야 합니다.localStorage
페이지 로드 시 가져옵니다.에서 액션을 디스패치하려고 합니다.componentDidMount
고객님의App
컴포넌트: 이 컴포넌트에서는localStorage
localStorage에서 앱 상태를 유지해야 합니다.레독스의 창시자인 댄 아브라모프가 만든 튜토리얼입니다.
그렇게 해 주세요.프로젝트에 이 방법을 사용했습니다.
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()));
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;
따라서 사용자 리듀서는 항상 세션 스토리지에서 초기 값을 가져옵니다.(요건에 따라 local Storage로 푸시할 수도 있습니다.)
다음 사항을 확인해 주십시오.
한 가지 조건만 추가하면 됩니다.
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: localStorage.getItem('token') ? true : false }; // just add this condition here
case UNAUTH_USER:
return { ...state, authenticated: localStorage.getItem('token') ? true : false }; // just add this condition here also
case AUTH_ERROR:
return { ...state, error: action.payload };
}
return state;
}
언급URL : https://stackoverflow.com/questions/46673204/react-redux-state-lost-after-refresh
'programing' 카테고리의 다른 글
TypeScript의 Angular Framework 오류 - "exportAs가 ngForm으로 설정된 지시문이 없습니다." (0) | 2023.02.24 |
---|---|
iframe 내부에서 iframe을 닫는 방법은? (0) | 2023.02.24 |
React on Drop이 실행되지 않습니다. (0) | 2023.02.24 |
컨트롤러를 테스트하기 위한 서비스 모킹 (0) | 2023.02.24 |
AngularJS에서 입력 트림을 비활성화하는 방법은 무엇입니까? (0) | 2023.02.24 |