React-Redux 문서 리뷰 및 사용법 확인 React Redux 7.1

study, share · 2021-6-15

← 리스트로

redux 문서 리뷰(React Redux 7.1)

리덕스 버전 React Redux 7.1 (React 16.18.3 or later)(https://redux.js.org/)

  • 앱의 예측 가능한 상태관리를 위한 컨테이너 라이브러리
  • 액션, 리듀서, 스토어의 개념과 사용방법을 명확히 안다
    • 툴킷이나 다른 유틸리티를 쓰지 않고 일반 함수 객체를 정의하여 생성할수 있다.
    • toolKit api의 createSlice, createReducer 이용해서 생성할수도 있다.
    • 유틸 모듈인 redux-actions 를 이용해 액션 생성 및 리듀서를 생성할수 있다.
      • (toolKit api에서도 동일한 기능의 api를 제공하므로 toolkit을 사용하는것이 좋아보인다.)

기본 사용법

// Provider
import React from 'react'
import ReactDOM from 'react-dom'

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

import App from './App'

const rootElement = document.getElementById('root')
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  rootElement
)

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

export function Counter() {
  const count = useSelector(selectCount)
  const dispatch = useDispatch()

  return (
    <div>
      <div className={styles.row}>
        <button
          className={styles.button}
          aria-label="Increment value"
          => dispatch(increment())}
        >
          +
        </button>
        <span className={styles.value}>{count}</span>
        <button
          className={styles.button}
          aria-label="Decrement value"
          => dispatch(decrement())}
        >
          -
        </button>
      </div>
      {/* omit additional rendering output here */}
    </div>
  )
}

toolkit API

configureStore

  • toolkit의 configureStore 함수로 스토어를 간편하게 만들 수 있다.
  • 기존 createStore와 다른점?

createSlice

  • createSlice나 createReducer는 기본적으로 Immer 기능을 제공한다.
  • 각 리듀서에 prepare메서드를 정의하여 액션의 인자를 받을수 있다.
  • 액션과 리듀서를 하나의 객체로 정의 하여 사용할 수 있다.
    import { createSlice } from '@reduxjs/toolkit'
    export const counterSlice = createSlice({
      name: 'counter',
      initialState: {
        value: 0
      },
      reducers: {
        increment: state => {
          // Redux Toolkit allows us to write "mutating" logic in reducers. It
          // doesn't actually mutate the state because it uses the Immer library,
          // which detects changes to a "draft state" and produces a brand new
          // immutable state based off those changes
          state.value += 1
        },
        decrement: state => {
          state.value -= 1
        },
        incrementByAmount: (state, action) => {
          state.value += action.payload
        }
      }
    })
    
    // Action creators are generated for each case reducer function
    export const { increment, decrement, incrementByAmount } = counterSlice.actions
    
    export default counterSlice.reducer
    

Hook

useSelect

  • 함수형 컴포넌트에서 store로 부터 값을 가져올때 사용

useDispatch

  • 함수형 컴포넌트에서 액션을 실행할때 사용

With Typescript

  • 타입스크립트와 함께 사용할때 hook.ts를 정의해 놓고 아래처럼 사용하면 편리하다
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
import type { RootState, AppDispatch } from './store'

// Use throughout your app instead of plain `useDispatch` and `useSelector`
export const useAppDispatch = () => useDispatch<AppDispatch>()
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector

비동기 동작을 위한 Thunk 미들웨어 사용하기

  • 리덕스 앱에 비동기 로직을 넣을 필요성이 있을경우 사용을 권장.
  • Redux Toolkit’s configureStore 를 사용하면 미들웨어를 추가할 필요없이 기본적으로 세팅이 되어있다.
  • createAsyncThunk API를 사용하고, createSlice에 extraReducor의 pending, fulfilled, rejected를 구현하면 api 대기, 성공, 실패의 상태 구현을 손쉽게 구현할수 있다.

redux-saga 개념 과 사용법 둘러봄