일반적인 컴포넌트 개발시에는 상태값(변수)을 관리하기 위해 라이프사이클이나 hooks을 사용한다.
이 경우 각각의 컴포넌트가 관리하는 변수값들이 소스파일 여기저기에 흩어져 있기 때문에 코드 유지보수에 좋지 않다.
컴포넌트의 상태 업데이트 관련 로직을 다른 파일로 분리시켜서 더욱 효율적으로 관리할 수 있다.
즉, 여러 개의 컴포넌트가 개별적으로 관리하는 상태값들을 하나의 소스에 모아 놓고 통합 관리하는 것이 목적.
컴포넌트끼리 상태를 공유해야 할 때도 여러 컴포넌트를 거치지 않고 손쉽게 상태 값을 전달하거나 업데이트할
수 있다.

Slice
Store
Component
미들웨어로 수행하는 처리들
전달받은 액션을 단순히 콘솔에 기록 전달받은 액션 정보를 기반으로 액션을 아예 취소 다른 종류의 액션을 추가로 디스패치 비동기 액션 처리 등
동작순서
[사용자 이벤트] ――▶ [액션함수 디스패치] ――▶ [미들웨어 자동실행] ――▶ [리듀서의 액션함수 실행됨] ――▶ [액션값이 갱신됨]
/src/store.js
// 폴더와 파일을 직접 생성해야 함.
import { configureStore } from '@reduxjs/toolkit';
const store = configureStore({
 // 개발자가 직접 작성한 Slice 오브젝트들이 명시되어야 한다.
 reducer: {
 ...
 }
});
export default store;
/src/index.js
// 리덕스를 위한 참조 추가
/** 리덕스 구성을 위한 참조 */
import { Provider } from 'react-redux';
import store from './store';
// 렌더링 처리
// 렌더링 처리를 <Provider store={store}> 태그로 감싼다.
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
 <Provider store={store}>
 <BrowserRouter>
 <App />
 </BrowserRouter>
 </Provider>
);
/src/slices/slice이름.js
동기처리인 경우 (Ajax 사용 안하는 경우)
reducers
import { createSlice } from '@reduxjs/toolkit'
const slice이름 = createSlice({
 name: 'slice이름',
 // 이 모듈이 관리하고자하는 상태값들을 명시
 initialState: {
 변수1: 100,
 변수2: 200
 },
 // 상태값을 갱신하기 위한 함수들을 구현
 // 컴포넌트에서 이 함수들을 호출할 때 전달되는 파라미터는 action.payload로 전달된
다.
 // initialState와 동일한 구조의 JSON을 리턴한다.
 reducers: {
 액션함수1: (state, action) => {...state},
 액션함수2: (state, action) => {...state}
 }
});
// 액션함수들 내보내기
export const { 액션함수1, 액션함수2 } = slice이름.actions;
// 리듀서 객체 내보내기
export default slice이름.reducer;
비동기처리인 경우 (Ajax를 사용하는 경우)
extraReducers
  import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
  import axios from 'axios';
  const API_URL = '...';
  /** Ajax처리를 위한 미들웨어 함수 정의 */
  export const 함수이름 = createAsyncThunk("slice이름/함수이름", async (payload, {
  rejectWithValue }) => {
     let result = null;
     try {
     result = await axios.get|post|put|delete(API_URL);
     } catch (err) {
     result = rejectWithValue(err.response);
     }
     return result;
  });
  const slice이름 = createSlice({
     name: 'slice이름',
     // 이 모듈이 관리하고자하는 상태값들을 명시
     initialState: {
         data: null,
         loading: false,
         error: null
     },
     // 상태값을 갱신하기 위한 함수들을 구현
     // Ajax의 처리 과정에 따라 자동으로 실행된다.
     extraReducers: {
       // 로딩중임을 표시
       [함수이름.pending]: (state, { payload }) => {
         return { ...state, loading: true }
       },
       // 처리가 완료된 경우 - 미들웨어 함수가 정상적으로 리턴한 경우
       [함수이름.fulfilled]: (state, { payload }) => {
         return {
             data: payload?.data,
             loading: false,
             error: null
         }
       },
       // 처리에 실패한 경우 - 미들웨어 함수 안에서 예외가 발생하여 catch블록이 실행된 경우
       [함수이름.rejected]: (state, { payload }) => {
         return {
             data: payload?.data,
             loading: false,
             error: {
                 code: payload?.status ? payload.status : 500,
                 message: payload?.statusText ? payload.statusText : 'Server Error'
             }
         }
       }
     },
  });
  export default Slice파일이름.reducer;
/src/slice/store.js
import { configureStore } from '@reduxjs/toolkit';
import slice이름 from './slices/slice이름';
const store = configureStore({
 // 개발자가 직접 작성한 Slice 오브젝트들이 명시되어야 한다.
 reducer: {
 slice이름: slice이름,
 ...
 },
 // 비동기 미들웨어 추가 (Ajax처리가 필요한 경우만 설정)
 middleware: (getDefaultMiddleware) => getDefaultMiddleware({serializableCheck:
false}),
});
export default store;
필요한 기능 참조하기
// 상태값을 로드하기 위한 hook과 action함수를 dispatch할 hook 참조
import { useSelector, useDispatch } from 'react-redux'
// Slice에 정의된 함수 참조
// - 동기처리인 경우에는 리듀서 내의 액션함수 참조
// - 비동기 처리인 경우에는 Slice 내의 미들웨어 함수 참조
import { 함수1, 함수2 } from '../slices/slice이름';
컴포넌트 내부에서 hook을 통해 필요한 Object 생성
// hook을 통해 slice가 관리하는 상태값 가져오기
const {변수1, 변수2} = useSelector((state) => state.slice이름);
// dispatch 함수 생성
const dispatch = useDispatch();
필요한 이벤트 핸들러 안에서 액션함수 디스패치하기
dispatch(함수1(파라미터));
dispatch(함수2(파라미터));