Redux는 전역 상태 관리 라이브러리
👉 쉽게 말해 "전역 저장소(store)"를 만들고
👉 필요한 데이터를 여러 컴포넌트가 공유할 수 있도록 관리하는 도구
✔ 여러 컴포넌트에서 같은 데이터를 사용할 수 있도록 함
✔ 컴포넌트끼리 데이터를 주고받을 때 props 전달이 필요 없음
✔ 데이터 흐름이 예측 가능하고, 유지보수가 쉬워짐
1️⃣ store (저장소) → 모든 상태(state)가 저장되는 곳
2️⃣ action (액션) → 상태를 변경하는 "명령" (ex: 상품 목록 가져오기)
3️⃣ reducer (리듀서) → 액션이 실행될 때, 새로운 상태로 변경하는 역할
4️⃣ dispatch (디스패치) → 액션을 실행하는 함수
5️⃣ useSelector() → store에서 데이터를 가져오는 함수
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); // 에러 발생 시 처리
}
}
);
이제 이 액션이 실행되면 Redux의 상태가 변경될 준비 완료.
상품 관련 상태(state)와 액션을 한 곳에서 관리
const productSlice = createSlice({
name: 'products',
initialState: {
productList: [], // 상품 목록
selectedProduct: null, // 선택된 상품 (상세 페이지에서 사용)
loading: false, // 로딩 상태
error: '', // 에러 메시지
totalPageNum: 1, // 총 페이지 수
success: false, // 요청 성공 여부
},
productList → 상품 목록selectedProduct → 선택된 상품 정보loading → 데이터 요청 중인지 확인error → 에러 메시지success → 요청 성공 여부Redux에서 API 요청이 진행될 때 상태를 업데이트하려면 extraReducers를 사용해야 합니다.
.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; // 에러 저장
});
loading = trueloading = falseloading = false→ dispatch(getUserProductList()) 실행
→ /product 요청 (카테고리, 검색어 적용)
→ loading = true (로딩 UI 표시)
→ productList에 데이터 저장
→ loading = false
→ error에 에러 메시지 저장
→ loading = false