ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [React Native] Redux Toolkit을 활용해 로그인 상태에 따라 페이지 전환하기
    프론트엔드/React 2023. 4. 7. 10:27

     

    틀린 내용이 있을 수 있습니다.
    발견하시면 말씀 부탁드립니다! 🙇


     

     

    진행하고 있는 개인 프로젝트는 그렇게 복잡한 구조가 아닌지라 Redux를 사용할 생각은 없었다. 하지만 프로젝트를 진행할수록 Redux의 필요성을 절실히 느꼈다. 한 가지 예로 로그아웃 기능을 구현할 때 마이페이지 부분에서 login state를 true → false로 변경하고 이 state값을 로그인 페이지까지 끌어올려야 하는 과정이 번거롭고 코드가 지저분해지는 것이었다. 결국 Redux를 사용하기로 결정! 업무에서 Redux를 사용해 본 경험이 있지만 입사했을 때부터 기존 코드에 있었던지라 그에 맞춰 사용한 정도였지 세팅을 한 건 이번이 처음이었다. 

     

     

    문제: 중첩된 네비게이터를 거쳐 state를 관리하기 힘들다. 

    결론: Redux store에서 state를 관리해서 사용하자!

     

     

    Redux  환경 세팅

    1. Redux toolkit, react-redux 패키지 설치

    npm install @reduxjs/toolkit react-redux
    npm install react-redux

    Redux toolkit은 Redux의 일반적인 3가지 흔한 문제점을 해결하기 위해 만들어졌는데 그 문제점은 아래와 같다.

    1. Redux store 설정하는게 복잡하고,
    2. Redux를 사용하기 위해서는 많은 패키지를 설치해야 하며,
    3. Redux는 bolierplate code(반복적으로 비슷한 형태의 코드)가 많다는 것이다.

    한 마디로 보다 더 쉽게 Redux를 사용할 수 있게 하는 패키지라는 것.

     

     

    2. Redux store 생성

    Redux store는 Redux toolkit에 내장된 configureStore 함수를 통해 생성할 수 있다. configureStore에는 위 코드와 같이 reducer 인수를 넘겨줘야 한다. 우리가 만드는 앱은 여러 가지 기능들로 이루어져 있을 것이고 각 기능들은 각자만의 reducer 함수를 가진다. configureStore를 호출할 때 하나의 객체에 있는 서로 다른 리듀서들을 전달할 수 있으며, 객체의 키는 최종 상태 값을 정의한다.

    // <프로젝트 루트경로>/src/store.js
    
    import { configureStore } from "@reduxjs/toolkit";
    import manageLoginStateReducer from './slices/manageLoginSlice';
    
    const store = configureStore({
      reducer: {
        manageLoginState: manageLoginStateReducer
      },
    });
    
    export default store;

    여기서는 slices 폴더에 있는 manageLoginSlice.js라는 파일에서 reducer 함수를 가져와 store를 생성했다. { key: keyReducer } - 위 코드에서 { manageLoginState: manageLoginStateReducer }에 해당함- 형태의 객체를 전달할 때, 이는 redux state 객체에 state.key라는 섹션을 마련하고 싶다는 의미이다. keyReducer 함수 액션이 발생했을 때 key의 업데이트 여부 및 업데이트 방법을 정하도록 한다.

     

     

    3. Redux state slice 생성

    slices 폴더에 있는 manageLoginSlice.js 파일을 보자. manageLoginState라는 상태의 초기 값은 false initialState:  { value: false }-이고 reducer와 state에 해당하는 action creator와 action type을 생성한다.

    // <프로젝트 루트경로>/src/redux/slices/manageLoginSlice.js
    
    import { createSlice } from "@reduxjs/toolkit";
    
    export const manageLoginSlice = createSlice({
      name: 'manageLoginState',
      initialState: {
        value: false,
      },
      reducers: {
        login: state => {
          state.value = true;
        },
        logout: state => {
          state.value = false;
        },
      },
    });
    
    export const { login, logout } = manageLoginSlice.actions;
    
    export default manageLoginSlice.reducer;

    slice라는 개념이 와닿지 않아 찾아보니 공식문서에 이렇게 나와 있었다.

    A "slice" is a collection of Redux reducer logic and actions for a single feature in your app, typically defined together in a single file. The name comes from splitting up the root Redux state object into multiple "slices" of state.

    "slice"는 한 기능에 속한 Redux reducer의 로직과 액션의 모음이며, 큰 덩어리인 Redux state를 여러 개의 state 조각들로 나누기 때문에 slice라는 이름이 나왔다고... 

     

    store와 slice파일까지 만든 상태에서 파일 구조는 아래와 같다. (redux 폴더에 관련된 것들을 몰아넣을 생각이다)

     

    4. provider 적용

    처음에는 App.js 파일 안에서 곧바로 Provider를 적용했지만 에러가 발생하여 AppWrapper.js 파일을 별도로 만들었다. 그다음 index.js 파일에서 AppWrapper.js를 불러와 Provider를 적용했다. AppWrapper.js 파일은 별거 없다. 그냥 Provider로 App 컴포넌트를 감싼 게 끝이다.

    // <프로젝트 루트경로>/AppWrapper.js
    
    import { Provider } from 'react-redux';
    import App from '../App';
    import store from './redux/store';
    
    export const AppWrapper = () => {
      return (
        <Provider store={store}>
          <App /> 
        </Provider>
      );
    };
    // <프로젝트 루트경로>/index.js 
    
    import { AppRegistry } from 'react-native';
    import { name as appName } from './app.json';
    import { AppWrapper } from './src/AppWrapper';
    
    AppRegistry.registerComponent(appName, () => AppWrapper);

     

     

    5. Redux 사용해서 State값 관리하기

    로그아웃 버튼을 클릭하면 리덕스 스토어 값을 수정하여 사용자의 로그인 여부를 관리할 수 있다.

      const pressLogout = () => {
        // ...
        // redux store value false 처리
        dispatch(logout());
      };

     

     

     

     

    따봉 리덕스야 고마워!

     

     


    참고 자료

     

    댓글

jaejade's blog ٩( ᐛ )و