반응형
Redux Toolkit이란
Redux의 공식 도구 모음, 복잡한 설정과 반복적인 코드를 줄이고 Redux를 더 쉽게 사용할 수 있도록 만들어 짐
직관적인 API, 코드 간소화, 미들웨어 기본 제공 등의 장점을 제공하며,
특히 아래와 같은 함수를 제공함
- createSlice (Action, Reducer)
- configureStore (Store)
- createAsyncThunk
설치
npm install @reduxjs/toolkit react-redux
(공식 문서에서도 RTK를 사용할 것을 권장)
Redux와 차이점
- 설정 간소화 : Redux는 기본 설정 시 store, reducer, 미들웨어 등 각각 설정해야함. Redux Toolkit은 이를 단일 파일로 간단하게 구성할 수 있음
- 코드 축소 : Redux는 액션, 리듀서, 액션 타입 등을 별도로 정의해야 하지만 Redux Toolkit은 createSlice를 통해 이 모든 것을 한번에 정의할 수 있음
- 비동기 작업 지원 : Redux는 비동기 처리가 기본 제공되지 않지만, Redux Toolkit은 createAsyncThunk로 비동기 로직을 쉽게 작성할 수 있음
- 내장된 미들웨어 : Redux Toolkit은 redux-thunk와 같은 미들웨어를 기본으로 제공하여 설정이 간편함
createSlice(), configureStore()의 역할
createSlice()
- Redux에서 액션(타입, 생성자)과 리듀서를 한 번에 작성할 수 있게 해주는 함수
- 슬라이스(slices)라는 단위로 상태를 관리하며, 상태 초기화, 액션 정의, 리듀서 함수 등을 한 파일에서 작성할 수 있음
- reducers 속성 안에서 상태를 변경하는 함숟르을 정의하면 Redux Toolkit이 자동으로 액션 생성자와 액션 타입을 만들어 줌
import { createSlice } from '@reduxjs/toolkit';
const counterSlice = createSlice({
name: 'counter',
initialState: { value: 0 },
reducers: {
increment: (state) => { state.value += 1; },
decrement: (state) => { state.value -= 1; },
},
});
export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;
configureStore()
- 리듀서를 전달받아 전역 상태 저장소를 생성
- Redux의 createStore를 대처하는 Redux Toolkit함수로, reducer, 미들웨어, 개발 도구(DevTools) 설정을 간단하게 할 수 있음
- 미들웨어가 기본 내장되어 있으며, 여러 슬라이스의 리듀서를 쉽게 통합할 수 있음
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './counterSlice';
const store = configureStore({
reducer: {
counter: counterReducer,
},
});
export default store;
Redux Toolkit에서 Thunk 사용법
Redux Toolkit에서는 redux-thunk
가 기본 미들웨어로 포함되어 있으므로, dispatch()
로 비동기 함수를 사용할 수 있음
기존 Redux와 다르게 추가 설정이 필요하지 않으며, createAsyncThunk
를 사용하는 것이 일반적임
createAsyncThunk()란
비동기 작업을 간편하게 작성하고 상태를 관리할 수 있는 함수
비동기 작업의 시작, 성공, 실패 세 가지 상태를 자동으로 생성해 주기 때문에 API 요청 시 pending
, fulfilled
, rejected
등의 상태를 손쉽게 다룰 수 있음
- configureStore 설정
// store.js
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './counterSlice';
const store = configureStore({
reducer: {
counter: counterReducer,
},
});
export default store;
- createSlice와 createAsyncThunk를 이용하여 비동기 카운터 기능 구현
// counterSlice.js
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
// 비동기 카운터 증가 동작 정의 (1초 후 증가)
export const incrementAsync = createAsyncThunk(
'counter/incrementAsync',
async (amount) => {
await new Promise((resolve) => setTimeout(resolve, 1000));
return amount;
}
);
const counterSlice = createSlice({
name: 'counter',
initialState: {
value: 0,
status: 'idle', // 'idle' | 'loading' | 'succeeded' | 'failed'
},
reducers: {},
extraReducers: (builder) => {
builder
.addCase(incrementAsync.pending, (state) => {
state.status = 'loading';
})
.addCase(incrementAsync.fulfilled, (state, action) => {
state.value += action.payload;
state.status = 'succeeded';
})
.addCase(incrementAsync.rejected, (state) => {
state.status = 'failed';
});
},
});
export default counterSlice.reducer;
- 컴포넌트에서 useSelector로 상태를 가져오고, useDispatch로 비동기 카운터 증가 액션 호출
// App.js
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { incrementAsync } from './counterSlice';
function App() {
const dispatch = useDispatch();
const counter = useSelector((state) => state.counter.value);
const status = useSelector((state) => state.counter.status);
return (
<div className="App">
<h1>Counter: {counter}</h1>
<button
onClick={() => dispatch(incrementAsync(1))}
disabled={status === 'loading'}
>
{status === 'loading' ? 'Loading...' : 'Increment after 1 second'}
</button>
</div>
);
}
export default App;
- 스토어를 Provider로 감싸 리덕스 상태를 사용할 수 있게 설정
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';
ReactDOM.createRoot(document.getElementById('root')).render(
<Provider store={store}>
<App />
</Provider>
);
- incrementAsync: createAsyncThunk를 사용해 1초 후에 카운트가 증가하는 비동기 동작 정의
- extraReducers: pending, fulfilled, rejected 상태에 따라 로딩 상태를 설정하고, fulfilled시 카운트 증가
- App 컴포넌트: 버튼 클릭 시 incrementAsync를 실행하여 상태 변화와 로딩 메시지를 확인할 수 있음
반응형
'FE > React & Redux' 카테고리의 다른 글
React | 상태관리와 useState (0) | 2024.10.29 |
---|---|
React | State와 Props 데이터 관리 (0) | 2024.10.29 |
React | Redux 전역 상태 관리 (2) | 2024.10.28 |
React | Context API (2) | 2024.10.25 |
React | 전역상태 관리 (2) | 2024.10.25 |