๐Ÿ—“ Redux toolkit์œผ๋กœ todo list ๋งŒ๋“ค๊ธฐ

์›์ง€ยท2023๋…„ 2์›” 16์ผ
0

๐Ÿ”Ž Redux toolkit์ด๋ž€ ?

์ƒํƒœ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค.

react๋Š” props ํ˜•ํƒœ๋กœ ์ปดํฌ๋„ŒํŠธ ๊ฐ„ ์ƒํƒœ๋ฅผ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋ผ๋ฆฌ๋Š” ์ƒํƒœ ๊ณต์œ ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ณ , ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งŽ์•„์งˆ ๊ฒฝ์šฐ ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฑฐ์ณ props๊ฐ€ ์ „๋‹ฌ๋˜๋Š” props drilling์ด ๋ฐœ์ƒํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ์˜ ๊ทœ๋ชจ๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ์ƒํƒœ๊ด€๋ฆฌ๋Š” ๋” ์–ด๋ ค์›Œ์ง€๋Š”๋ฐ, ์ด๋Ÿฌํ•œ ๋ฌธ์ œ์ ์„ ํ•ด๊ฒฐํ•˜๊ณ ์ž ์ „์—ญ์ ์œผ๋กœ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์ƒํƒœ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

Redux toolkit์€ Redux์˜ ์ž‘์—…์„ ๋‹จ์ˆœํ™”ํ•˜์—ฌ ๊ธฐ์กด์˜ ๋ณต์žกํ•œ ์‚ฌ์šฉ ๋ฐฉ์‹๊ณผ ๋น„๋Œ€ํ•œ ๋ณด์ผ๋Ÿฌ ํ”Œ๋ ˆ์ดํŠธ ๋ฌธ์ œ ๋“ฑ์„ ํ•ด๊ฒฐํ•œ ์ƒํƒœ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค.

๐Ÿ’ป ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

import { configureStore } from '@reduxjs/toolkit'

export default configureStore({
  reducer: { }
}) 

redux toolkit์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” store.js ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜์—ฌ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” store๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

import { Provider } from "react-redux";
import App from "./App";
import { store } from './store';

const Homework = () => {
  return (
    <>
      <Provider store={store}>
        <App />
      </Provider>
    </>
  );
};

export default Homework;

์ „์—ญ์—์„œ ์ƒํƒœ๋ฅผ ๊ณต์œ ํ•˜๊ธฐ ์œ„ํ•ด App์„ Provider๋กœ ๊ฐ์Œ‰๋‹ˆ๋‹ค.

๐Ÿ“ store์˜ state ๊ฐ€์ ธ๋‹ค์“ฐ๋Š” ๋ฒ•

const initialState: initialState = {
  todos: [{id: 1, title: 'ํ•  ์ผ'}]
}

const todosSlice = createSlice({
  name: 'todos',
  initialState,
  reducers: {
  }
})

export const store = configureStore({
  reducer: {
    getTodos: todosSlice.reducer
  }
})

createSlice()๋Š” slice๋ฅผ ๋งŒ๋“œ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. name์€ slice๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ๋‚ด๋ถ€์ ์œผ๋กœ ์ค‘๋ณต์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ์ด๋ฆ„, initialState๋Š” ์ดˆ๊ธฐ ์ƒํƒœ๊ฐ’, reducer๋Š” ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

configureStore()์—๋Š” slice ๋“ฑ๋กํ•ด ์ „์—ญ์—์„œ ์ƒํƒœ๊ด€๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const todos = useSelector((state: ReturnType<typeof store.getState>) => state.getTodos.todos)

์ปดํฌ๋„ŒํŠธ์—์„œ useSelector๋ฅผ ์‚ฌ์šฉํ•ด store์— ์žˆ๋˜ slice๋ฅผ ํ˜ธ์ถœํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“ store์˜ state ๋ณ€๊ฒฝํ•˜๋Š” ๋ฒ•

const todosSlice = createSlice({
  name: 'todos',
  initialState,
  reducers: {
    addTodo: (state, action: PayloadAction<string>) => {
      state.todos = [
        {id: Date.now() , title: action.payload},
        ...state.todos
      ]
    },
    deleteTodo: (state, action: PayloadAction<number>) => {
      state.todos
      = state.todos.filter(todo => todo.id !== action.payload)
    }
  }
})

export const {addTodo, deleteTodo} = todosSlice.actions

reducer๋Š” ์ƒํƒœ์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ฒฐ์ •ํ•˜๊ณ  ์—…๋ฐ์ดํŠธ ๋œ ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. reducer๋ฅผ ํ†ตํ•ด store์˜ ๋‚ด๋ถ€ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

todoSlice์˜ reducer์— todo๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” addTodo ํ•จ์ˆ˜์™€, ์‚ญ์ œํ•˜๋Š” deleteTodo ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

reducer๋ฅผ ์ „์—ญ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” slice์˜ ์ด๋ฆ„๋’ค์— .actions๋ฅผ ๋ถ™์—ฌ export ํ•ฉ๋‹ˆ๋‹ค.

const dispatch = useDispatch()

  const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault()
    dispatch(addTodo(input))
    setInput('')
  }

์ƒํƒœ๋ณ€๊ฒฝ์„ ์›ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์—์„œ useDispatch๋ฅผ ์‚ฌ์šฉํ•ด Action์„ ์ „๋‹ฌํ•˜๋ฉด

์งœ์ž” ! todo๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์ถ”๊ฐ€๋˜๊ณ  ์‚ญ์ œ๋˜๋„ค์š” ใ…Žใ…Ž

0๊ฐœ์˜ ๋Œ“๊ธ€