이번 포스팅에서는 Redux Toolkit을 사용하여 포켓몬 도감 애플리케이션의 상태 관리를 구현하는 방법을 살펴보겠습니다. Redux Toolkit을 사용하면 복잡한 상태 관리 로직을 간단하고 직관적으로 구현할 수 있습니다. 이번 글에서는 Redux의 기초부터 상태를 중앙에서 관리하는 방법까지 설명합니다.
Redux Toolkit은 Redux의 공식 툴킷으로, 보일러플레이트 코드 없이 상태 관리를 쉽게 시작할 수 있습니다. 이번 프로젝트에서 Redux Toolkit을 사용해 포켓몬 목록과 즐겨찾기 상태를 관리할 것입니다.
configureStore
: 간편하게 스토어를 설정할 수 있습니다.createSlice
: 리듀서와 액션을 한 번에 생성하여 코드의 간결함을 높입니다.createAsyncThunk
: 비동기 API 호출을 쉽게 처리할 수 있습니다.store.js 파일을 생성하고, configureStore
를 사용하여 스토어를 설정합니다.
import { configureStore } from '@reduxjs/toolkit';
import pokemonReducer from './pokemonSlice';
import favoriteReducer from './favoriteSlice';
import languageReducer from './languageSlice';
export const store = configureStore({
reducer: {
pokemon: pokemonReducer,
favorite: favoriteReducer,
language: languageReducer,
},
});
createSlice
를 사용하여 포켓몬 데이터와 즐겨찾기 목록을 관리하는 슬라이스를 만듭니다.
포켓몬 목록을 관리하기 위한 slice를 생성합니다. 이 slice는 포켓몬 데이터를 API로부터 비동기적으로 가져와 상태를 업데이트합니다.
import { createSlice } from '@reduxjs/toolkit';
import { fetchPokemonData } from './pokemonThunks';
export const pokemonSlice = createSlice({
name: 'pokemon',
initialState: {
data: [],
loading: false,
},
reducers: {},
extraReducers: (builder) => {
builder
.addCase(fetchPokemonData.pending, (state) => {
state.loading = true;
})
.addCase(fetchPokemonData.fulfilled, (state, action) => {
state.loading = false;
state.data = action.payload;
})
.addCase(fetchPokemonData.rejected, (state) => {
state.loading = false;
});
},
});
export default pokemonSlice.reducer;
즐겨찾기 기능을 구현하기 위한 slice입니다.
import { createSlice } from '@reduxjs/toolkit';
export const favoriteSlice = createSlice({
name: 'favorite',
initialState: [],
reducers: {
addToFavorite: (state, action) => {
state.push(action.payload);
},
removeFromFavorite: (state, action) => {
return state.filter((pokemonId) => pokemonId !== action.payload);
},
},
});
export const { addToFavorite, removeFromFavorite } = favoriteSlice.actions;
export default favoriteSlice.reducer;
createAsyncThunk
를 사용하여 포켓몬 데이터를 비동기적으로 가져옵니다. 이를 통해 API 요청과 응답을 관리하고, 상태를 업데이트할 수 있습니다.
import { createAsyncThunk } from '@reduxjs/toolkit';
export const fetchPokemonData = createAsyncThunk(
'pokemon/fetchPokemonData',
async () => {
const response = await fetch('https://pokeapi.co/api/v2/pokemon?limit=151');
const data = await response.json();
return data.results;
}
);
useSelector
와 useDispatch
훅을 사용하여 Redux 상태를 컴포넌트에서 활용합니다.
포켓몬 목록을 화면에 표시하기 위해 useSelector
로 상태를 가져오고, useDispatch
로 데이터를 가져오는 액션을 디스패치합니다.
import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { fetchPokemonData } from '../RTK/pokemonThunks';
import Card from '../components/Card';
function Main() {
const dispatch = useDispatch();
const pokemonData = useSelector((state) => state.pokemon.data);
const loading = useSelector((state) => state.pokemon.loading);
useEffect(() => {
dispatch(fetchPokemonData());
}, [dispatch]);
if (loading) {
return <div>Loading...</div>;
}
return (
<div className="pokemon-list">
{pokemonData.map((pokemon, index) => (
<Card key={index} pokemon={pokemon} />
))}
</div>
);
}
export default Main;
createAsyncThunk
를 사용하여 API 호출과 상태 업데이트를 쉽게 관리할 수 있습니다.이번 글에서는 Redux Toolkit을 사용하여 포켓몬 도감 애플리케이션의 상태 관리를 구현했습니다. 상태를 중앙에서 관리하여 데이터의 일관성을 유지하고, 비동기적으로 데이터를 가져오는 방법까지 배웠습니다. 다음 파트에서는 i18next를 사용하여 다국어 지원을 구현하는 방법을 다룰 예정입니다.