Redux 개념

henry·2024년 9월 30일

🌟 Redux란?

Redux는 전역 상태 관리 라이브러리

👉 쉽게 말해 "전역 저장소(store)"를 만들고
👉 필요한 데이터를 여러 컴포넌트가 공유할 수 있도록 관리하는 도구


🔥 왜 Redux를 사용할까?

✔ 여러 컴포넌트에서 같은 데이터를 사용할 수 있도록 함
✔ 컴포넌트끼리 데이터를 주고받을 때 props 전달이 필요 없음
✔ 데이터 흐름이 예측 가능하고, 유지보수가 쉬워짐


🎯 Redux의 핵심 개념

1️⃣ store (저장소) → 모든 상태(state)가 저장되는 곳
2️⃣ action (액션) → 상태를 변경하는 "명령" (ex: 상품 목록 가져오기)
3️⃣ reducer (리듀서) → 액션이 실행될 때, 새로운 상태로 변경하는 역할
4️⃣ dispatch (디스패치) → 액션을 실행하는 함수
5️⃣ useSelector()store에서 데이터를 가져오는 함수

✅ 정리

  • Redux는 store(저장소)에 있는 상태(state)를 가져오고,
  • dispatch(디스패치)를 사용해 상태를 변경하는 구조로 동작합니다.

📌 Redux Toolkit을 활용한 비동기 로직 처리 (createAsyncThunk)

✅ 1️⃣ 비동기 액션 만들기

API 요청을 보낼 때는 비동기 액션(createAsyncThunk)을 사용

export const getUserProductList = createAsyncThunk(
   'products/getUserProductList',
   async ({ category = null, name = null }, { rejectWithValue }) => {
      try {
         const response = await api.get('/product', { params: { category, name } });
         return response.data;
      } catch (error) {
         return rejectWithValue(error.error); // 에러 발생 시 처리
      }
   }
);

✔ API 요청 → /product

✔ 요청 성공 시, response.data 반환

✔ 요청 실패 시, rejectWithValue(error.error)를 호출

이제 이 액션이 실행되면 Redux의 상태가 변경될 준비 완료.


📌 Redux Slice: 중앙에서 상태를 관리하는 역할

✅ 2️⃣ productSlice 만들기

상품 관련 상태(state)와 액션을 한 곳에서 관리

const productSlice = createSlice({
   name: 'products',
   initialState: {
      productList: [],        // 상품 목록
      selectedProduct: null,  // 선택된 상품 (상세 페이지에서 사용)
      loading: false,         // 로딩 상태
      error: '',              // 에러 메시지
      totalPageNum: 1,        // 총 페이지 수
      success: false,         // 요청 성공 여부
   },

✅ 초기 상태 정의

  • productList → 상품 목록
  • selectedProduct → 선택된 상품 정보
  • loading → 데이터 요청 중인지 확인
  • error → 에러 메시지
  • success → 요청 성공 여부

📌 Redux 비동기 요청 상태 관리 (extraReducers)

Redux에서 API 요청이 진행될 때 상태를 업데이트하려면 extraReducers를 사용해야 합니다.

✅ 3️⃣ 비동기 요청 상태 변화 관리

.extraReducers: (builder) => {
   builder
      .addCase(getUserProductList.pending, (state) => {
         state.loading = true; // ⏳ 로딩 시작
      })
      .addCase(getUserProductList.fulfilled, (state, action) => {
         state.loading = false; // ✅ 로딩 완료
         state.userProductList = action.payload.productList; // 상품 목록 저장
         state.error = ''; // 에러 초기화
      })
      .addCase(getUserProductList.rejected, (state, action) => {
         state.loading = false; // ❌ 로딩 종료
         state.error = action.payload; // 에러 저장
      });

1. API 요청을 보내면 pending 상태가 되고 loading = true

2. API 요청 성공(fulfilled) 시 userProductList에 데이터를 저장하고 loading = false

3. API 요청 실패(rejected) 시 error에 에러 메시지를 저장하고 loading = false


📌 Redux 흐름 한눈에 정리! 🏆

1️⃣ 사용자가 상품 목록을 보려고 하면

→ dispatch(getUserProductList()) 실행

2️⃣ Redux는 API 요청을 보냄

→ /product 요청 (카테고리, 검색어 적용)

3️⃣ API 요청이 진행되는 동안

→ loading = true (로딩 UI 표시)

4️⃣ 요청 성공 시 (fulfilled)

→ productList에 데이터 저장
→ loading = false

5️⃣ 요청 실패 시 (rejected)

→ error에 에러 메시지 저장
→ loading = false

✅ Redux는 요청 상태를 관리하면서, 컴포넌트에서 이를 가져와 UI를 업데이트함.


0개의 댓글