[react] Redux 사용하기 - 1. 리덕스 환경 구성

JCH27·2024년 10월 29일
0

react

목록 보기
8/8

오랜만의 블로그 글 작성이다.

취업은 여전히 어렵지만, 나는 키보드워리어 포기하지 않는다.


리덕스 사용법 - 리덕스 환경 구성

오늘은 Redux 사용법 중 환경을 구성하는 방법을 정리하도록 하고, 로그인 등의 로직 설계는 다음 글에서 정리하도록 하겠다.

redux는 클라이언트에서 전역 상태를 관리하기 위해 사용되는 라이브러리로 props drilling 없이 필요한 상태값을 불러올 수 있는 도구이다.


Redux, Redux Toolkit, Redux Persist, React-Redux에 대한 요약

우리는 redux에서 권장하는 @reduxjs/toolkit의 다양한 함수를 사용하여 전역 상태 관리 환경을 구성 할 예정이다.


1. Slice 생성하기

slice란? Redux Toolkit에서 제공하는 개념으로, 특정 상태와 그에 관련된 액션 및 리듀서들을 하나로 묶은 것입니다. 각각의 슬라이스는 Redux 상태의 한 부분을 관리하며, Redux Toolkit의 createSlice 함수로 생성할 수 있습니다.

createSlice 함수로 slice를 생성하면 slice가 정의된 action에 따라 reducer(함수)를 실행하여 전역 상태 한가지를 제어한다고 생각하면 편할 듯 하다.

createSlice 함수의 필수 항목!!!

  • name : Redux 액션 타입에 사용되므로 고유한 이름을 설정!!
  • initialState : 초기 상태값!!
  • reducers : 상태를 변경할 액션 함수들을 정의!!
  • extraReducers : 비동기적 로직을 실행하는 액션에 대하여 정리!!
import {createSlice} from '@reduxjs/toolkit';

// 초기 상태값읠 정의
const initialSlice = {
  userData : {
    name : '',
	id : '',
	role : 0,
  },
  isAuth : false,
  isLoading : false,
  error : ''
}

const userSlice = createSlice({
  name : 'user',
  initialState,
  reducers : {},
  extraReducers : (builder)=>{
    // builder 객체의 addCase메서드를 사용하여 비동기 로직을 정의한다.
    // ex) builder.addCase(비동기함수명.동작의상태 , (state, action)=>{
    //       실행 할 로직을 작성
    //     })
  }
});

// slice의 reducer들을 모두 export 하여 다른 스크립트에서 사용한다!
export default userSlice.reducer;

2. store 생성하기

store란? : 전체 전역 상태를 보관하는 객체로, Redux 상태 관리의 핵심 역할을 합니다. 모든 상태, 액션, 리듀서가 스토어와 연결되어 있으며, React 컴포넌트는 스토어를 통해 상태를 조회하거나 액션을 디스패치하여 상태를 변경합니다.

말 그대로 전역 상태를 저장하는 저장소라고 생각하면 좋을 듯하다

store를 생성하고 조작하는데 유용하게 쓰이는 함수들

  • combineReducers : 각각의 slice에 정의된 reducer들을 합치는 함수로 store의 여러 전역 상태값을 관리하기 위하여 사용한다.
  • persistReducer : 단일 reducer 혹은 합친 reducer를 지속시키기 위한 함수
  • configureStore : store를 생성하는 함수
  • persistStore : 정의된 store를 지속시키기 위한 함수

1. combineReducers 함수의 필수 항목!!!

  • {리듀서 키 : 리듀서}
	// 예시
	import combineReducer from '@reduxjs/toolkit';
	import userReducer from '../slices/userSlice.js';

	const combinedReducer = combineReducer({ user : userReducer });

2. persistReducer 함수의 필수 항목!!!

  • persistConfig : 지속옵션을 선언
  • combinedReducer : 합쳐진 혹은 하나의 리듀서
    // 예시
    import {persistReducer} from 'redux-persist';
	import {storage} from 'redux-persist/lib/storage';

	// persistReducer 함수에 할당하기 위한 선언
    const persistConfig = {
      // 키 : 값
      // storage or cookie
  	  key : 'root-underdog',
  	  storage
	};

	// 
	const persistedReducer = persistReducer(persistConfig, rootReducer);

3. configuerStore 함수와 persistStore 함수의 필수 항목!!!

  1. configureStore
  • reducer : 지속옵션으로 선언된 리듀서
  • middleware : 미들웨어 함수 (getDefaultMiddleware)
  1. persistStore
  • 생성된 스토어
// 예시
import {configuerStore} from '@reduxjs/toolkit';
import {FLUSH, PAUSE, PERSIST, PURGE, REGISTER, REHYDRATE, persistStore} from 'redux-persist';

// 스토어 생성
export const store = configureStore({
  reducer : persistedReducer,
  middleware : (getDefaultMiddleware) => 
    getDefaultMiddleware({
      serializableCheck : {
        ignoreActions : [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER]
      }
    })
});

// 스토어를 영구화
export const persistor = persistStore(store);

3. Provider 와 PersistGate로 전역 공간 정하기

  1. provider란? : 전역 공간을 적용하는 일종의 context와 같은 것으로 index.js에 하위 요소를 감싼다. PersistGate를 자식 요소로 둔다.

  2. PersistGate란? : Redux 스토어의 상태를 로컬 스토리지(localStorage, sessionStorage 등)에 저장하여, 브라우저 새로고침이나 페이지 이동 시에도 상태가 유지되도록 한다.

!!! PersistGate를 Provider로 감싸야 하는 이유 !!!

PersistGate의 동작 방식: PersistGate는 스토어에서 데이터를 불러오는 작업이 완료될 때까지 컴포넌트 렌더링을 지연시킵니다. 즉, PersistGate 안에 있는 모든 컴포넌트는 데이터가 준비될 때까지 렌더링되지 않습니다.
Provider의 역할: Provider는 스토어를 제공하는 역할만 합니다. 스토어의 데이터가 언제 준비되는지에 대한 제어는 하지 않습니다.
위치에 따른 차이:
PersistGate를 Provider 바깥에 감싸면: 모든 컴포넌트가 데이터가 준비되기 전에 렌더링될 수 있습니다. 이는 데이터가 아직 없음에도 불구하고 UI가 렌더링되어 버리는 문제를 야기할 수 있습니다.
PersistGate를 Provider 안쪽에 감싸면: PersistGate가 데이터를 불러오는 동안 컴포넌트 렌더링이 지연되어, 데이터가 준비된 후에야 UI가 렌더링됩니다.

// 예시
import {Provider} from 'react-redux';
import { persistor, store } from './store/store';
import { PersistGate } from 'redux-persist/integration/react';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <>
    <Provider store={store}>
      <PersistGate loading={null} persistor={persistor}>
          <App />
      </PersistGate>
    </Provider>
  </>
);

이렇게 redux 환경을 구성하는 방법을 정리했다. 다음 글에선 로그인 등의 로직을 적용하는 방법을 정리하도록 하겠다.

profile
포기하지 않는 키보드 워리어

0개의 댓글