programing

새로 고침 후 React-Redux 상태가 손실됨

telecom 2023. 2. 24. 13:15
반응형

새로 고침 후 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

반응형