반응형
3. 전역 상태 관리 분석: adminSlice.jsx
이 파일은 Redux Toolkit의 createSlice 기능을 사용하여 관리자 페이지에서 공통으로 사용되는 모든 데이터를 관리합니다. 이를 '전역 상태 관리'라고 하며, 여러 컴포넌트가 동일한 데이터에 접근하고 수정할 수 있게 해줍니다.
3.1. 코드 전문 (주석 포함)
// Redux Toolkit에서 createSlice 함수를 가져옵니다.
// createSlice는 리듀서와 액션을 한 번에 만드는 편리한 함수입니다.
import { createSlice } from "@reduxjs/toolkit";
// [1] 이 슬라이스(slice)에서 관리할 상태의 초기값을 정의합니다.
// 앱이 처음 시작될 때 이 값들로 상태가 채워집니다.
const initialState = {
genres: [], // 장르 목록을 저장할 배열
studies: [], // 교육(주제) 목록을 저장할 배열
exams: [], // 예문 목록을 저장할 배열
audios: [], // 음성 파일 목록을 저장할 배열
currentStudy: null, // 현재 보고 있거나 수정 중인 단일 교육 정보
currentExam: null, // 현재 보고 있거나 수정 중인 단일 예문 정보
loading: false, // API 요청 등 비동기 작업이 진행 중인지 여부 (예: 로딩 스피너 표시용)
error: null // 에러가 발생했을 때 에러 메시지를 저장
};
// [2] 'admin'이라는 이름의 슬라이스를 생성합니다.
const adminSlice = createSlice({
name: "admin", // 슬라이스의 이름. 이 이름은 액션 타입 생성 시 접두사로 사용됩니다. (예: 'admin/setGenres')
initialState, // 위에서 정의한 초기 상태
// reducers: 상태(state)를 어떻게 변경할지에 대한 로직을 담고 있는 함수들의 모음입니다.
reducers: {
// 각 리듀서 함수는 두 개의 인자를 받습니다: state와 action
// state: 현재의 상태 값 (Redux Toolkit이 내부적으로 불변성을 관리해줘서 직접 수정하는 것처럼 코딩 가능)
// action: 컴포넌트에서 보낸 요청 정보. action.payload에 전달된 데이터가 담겨 있습니다.
// --- 상태 설정(Set) 리듀서들 ---
// API를 통해 받아온 전체 데이터를 스토어에 저장합니다.
setGenres: (state, action) => { state.genres = action.payload; },
setStudies: (state, action) => { state.studies = action.payload; },
setExams: (state, action) => { state.exams = action.payload; },
setAudios: (state, action) => { state.audios = action.payload; },
setCurrentStudy: (state, action) => { state.currentStudy = action.payload; },
setCurrentExam: (state, action) => { state.currentExam = action.payload; },
setLoading: (state, action) => { state.loading = action.payload; },
setError: (state, action) => { state.error = action.payload; },
// --- 개별 데이터 추가/수정/삭제 리듀서들 ---
// (현재 프로젝트에서는 API 호출 후 전체 목록을 다시 불러오는 방식을 사용하므로, 아래 리듀서들은 직접 사용되지 않을 수 있습니다.)
// (하지만, 이런 방식도 가능하다는 것을 보여주는 좋은 예시입니다.)
// 새 데이터를 기존 배열에 추가
addGenre: (state, action) => { state.genres.push(action.payload); },
addStudy: (state, action) => { state.studies.push(action.payload); },
addExam: (state, action) => { state.exams.push(action.payload); },
addAudio: (state, action) => { state.audios.push(action.payload); },
// 특정 데이터를 수정
updateStudy: (state, action) => {
// studies 배열에서 수정할 항목의 인덱스를 찾습니다. (id가 일치하는 항목)
const index = state.studies.findIndex(s => s.studyNo == action.payload.studyNo);
// 인덱스를 찾았다면, 해당 위치의 데이터를 action.payload로 교체합니다.
if (index !== -1) { state.studies[index] = action.payload; }
},
// 특정 데이터를 삭제
deleteStudy: (state, action) => {
// action.payload로 전달된 studyNo와 일치하지 않는 항목들만 남겨서 새로운 배열을 만듭니다.
state.studies = state.studies.filter(s => s.studyNo !== action.payload);
},
deleteExam: (state, action) => {
state.exams = state.exams.filter(e => e.examNo !== action.payload);
},
deleteAudio: (state, action) => {
state.audios = state.audios.filter(a => a.audioNo !== action.payload);
},
},
});
// [3] 생성된 액션 생성자(Action Creators)들을 export 합니다.
// 컴포넌트에서 `dispatch(setGenres(data))` 와 같이 사용할 수 있게 됩니다.
export const {
setGenres,
setStudies,
setExams,
setAudios,
setCurrentStudy,
setCurrentExam,
setLoading,
setError,
addGenre,
addStudy,
addExam,
addAudio,
updateStudy,
deleteStudy,
} = adminSlice.actions;
// [4] 슬라이스의 리듀서를 export 합니다.
// 이 리듀서는 Redux 스토어 설정 파일(보통 store.js)에서 사용됩니다.
export default adminSlice.reducer;
3.2. 핵심 분석
createSlice의 역할: Redux의 3가지 주요 요소인 액션(Actions), 리듀서(Reducers), 상태(State)를 하나의 객체 안에서 모두 정의하게 해주는 강력한 도구입니다.createSlice덕분에 Redux 설정이 매우 간결해졌습니다.initialState: 이 슬라이스가 관리하는 모든 데이터의 '청사진' 또는 '초기 상태'입니다. 앱이 로드될 때 Redux 스토어는 이initialState를 기반으로admin상태를 구성합니다.reducers객체: 이 객체 안에 있는 함수들이 실제로 상태를 변경하는 로직을 담고 있습니다.- 예를 들어
setGenres: (state, action) => { state.genres = action.payload; }라는 리듀서는,setGenres라는 액션이 실행될 때state.genres의 값을action.payload(컴포넌트에서 전달한 새로운 장르 목록 데이터)로 교체하라는 의미입니다. - Immer 라이브러리: Redux Toolkit은 내부적으로
Immer라는 라이브러리를 사용합니다. 덕분에state.genres = ...나state.genres.push(...)처럼 상태를 직접 수정하는 것처럼 보이는 코드를 작성해도, 실제로는 불변성을 유지하며 안전하게 상태가 업데이트됩니다. (전통적인 Redux에서는return { ...state, genres: action.payload }와 같이 복잡하게 작성해야 했습니다.)
- 예를 들어
export의 두 종류:export const { ... } = adminSlice.actions;: 컴포넌트에서 상태 변경을 "요청"할 때 사용하는 액션 생성자 함수들을 내보냅니다.dispatch(setGenres(genresData))와 같이 사용됩니다.export default adminSlice.reducer;:createSlice가 생성한 리듀서 로직 전체를 내보냅니다. 이 리듀서는 스토어를 설정하는 파일(store.js등)에서 애플리케이션의 전체 리듀서에 통합됩니다.
반응형
'프로젝트 > 웹' 카테고리의 다른 글
| [React] 기타 컴포넌트 : 한국어 교육 웹 서비스 '재밌는한국어' 프로젝트 (1) | 2025.10.16 |
|---|---|
| [React] 수정 컴포넌트 : 한국어 교육 웹 서비스 '재밌는한국어' 프로젝트 (0) | 2025.10.16 |
| [React] 등록 컴포넌트 : 한국어 교육 웹 서비스 '재밌는한국어' 프로젝트 (0) | 2025.10.16 |
| [React] 전체 목록 컴포넌트 : 한국어 교육 웹 서비스 '재밌는한국어' 프로젝트 (0) | 2025.10.16 |
| [React] API 계층 분석 : 한국어 교육 웹 서비스 '재밌는한국어' 프로젝트 (0) | 2025.10.16 |
| [React] 프로젝트 구조 : 한국어 교육 웹 서비스 '재밌는한국어' 프로젝트 (0) | 2025.10.16 |