Redux

병근·2024년 4월 11일

최근 Next.js 프로젝트를 진행하면서 상태들을 관리해야 하는 작업이 자주 발생하고 코드가 불필요하게 길어지는 문제를 느꼈습니다. 이에 상태 관리 라이브러리를 사용하여 코드를 더 효율적으로 관리하고자 React-Redux를 공부하며 그 내용을 정리해놓으려 합니다.

리액트 리덕스는 무엇인가?

Redux는 JavaScript 애플리케이션을 위한 상태 관리 라이브러리로, React와 함께 사용되며 애플리케이션의 상태를 효율적으로 관리하고 사용자가 원하는 방식으로 업데이트하는 데 도움을 줍니다. 리덕스는 애플리케이션의 전역 상태를 단일 스토어(store)로 관리하고, 상태를 변경하기 위한 액션(action)리듀서(reducer)를 사용하여 상태를 업데이트합니다.

(1) React-Redux의 특징

1. Single source of truth
Redux는 한 곳에서 데이터를 전역적으로 관리한다.

2. State is read-only
기존의 상태를 변경하면 안된다.
즉, 불변성을 유지하며 상태를 변경해줘야 한다.

3. Changes are made with pure functions
변경은 순수 함수로만 가능하다.
즉, 동일한 입력값이 있다면 동일한 출력값이 있어야 한다.

(2) React-Redux 동작방식

(3) React-Redux의 구성 요소

store : 전역 상태를 관리하는 곳, 컴포넌트에서 어떠한 상태를 조회하고 싶다면 useSelector를 사용해 store에 접근하여 데이터를 얻어야 함
action : Reducer에게 어떤 동작을 수행해야 할 지 알려주는 역할
reducer : Action에 따라서 Store 값을 변경
dispatch : Action을 호출할 때 사용되는 함수

(4) React-Redux의 사용법

import { configureStore } from '@reduxjs/toolkit'

export default configureStore({
  reducer: {},
})

보통 src/app/store.js라는 파일을 만들고 configureStore을 이용해 Store를 생성 createStore는 이전 버전이라 사용되지 않음

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import store from './app/store'
import { Provider } from 'react-redux'

const root = ReactDOM.createRoot(document.getElementById('root'))

root.render(
  <Provider store={store}>
    <App />
  </Provider>,
)

Store 생성 후 로 태그를 감싸주어 이 Redux스토어를 사용할 수 있게 만들어 주어야합니다.

import { createSlice } from '@reduxjs/toolkit'

export const counterSlice = createSlice({
  name: 'counter',
  initialState: {
    value: 0,
  },
  reducers: {
    increment: (state) => {
      state.value += 1
    },
    decrement: (state) => {
      state.value -= 1
    },
    incrementByAmount: (state, action) => {
      state.value += action.payload
    },
  },
})

export const { increment, decrement, incrementByAmount } = counterSlice.actions

export default counterSlice.reducer

그후 counterSlice.js라는 이름의 파일을 만들고 Slice를 생성하여 Reducer와 Action상태를 정의합니다.
Slice를 생성하려면 name, 초기 상태 값, 그리고 상태 업데이트 방법을 정의하는 하나 이상의 리듀서 함수가 필요합니다.

import { configureStore } from '@reduxjs/toolkit'
import counterReducer from '../features/counter/counterSlice'

export default configureStore({
  reducer: {
    counter: counterReducer,
  },
})

그런 다음 Slice를 가져와 store에 추가해주면 됩니다.

import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment } from './counterSlice'
import styles from './Counter.module.css'

export function Counter() {
  const count = useSelector((state) => state.counter.value)
  const dispatch = useDispatch()

  return (
    <div>
      <div>
        <button
          aria-label="Increment value"
          onClick={() => dispatch(increment())}
        >
          Increment
        </button>
        <span>{count}</span>
        <button
          aria-label="Decrement value"
          onClick={() => dispatch(decrement())}
        >
          Decrement
        </button>
      </div>
    </div>
  )
}

원하는 파일에 useSelector를 사용해 변수의 상태를 가져오고 useDispatch를 사용해 Rudex store에 상태를 변경해주면 됩니다.

profile
꾸준히 하자!

0개의 댓글