본문 바로가기
웹/(React)리액트

상태관리 라이브러리, Redux 에 대해서/Redux Toolkit에 대해서

by 공부가싫다가도좋아 2023. 9. 15.
반응형

목차

1. Redux란?

2. Redux 주요 개념

3. Redux는 언제 필요할까?

4. Redux-Toolkit에 대해서

4-1. Redux-Toolkit 파일 구조

4-2. Redux-Toolkit 사용법


1. Redux란?

Flux개념을 바탕으로한 React에서 현재 가장 많이 사용되는 State 관리 라이브러리 입니다.

더보기

Flux는 Facebook에서 클라이언트-사이드 웹 어플리케이션을 만들기 위해 사용하는 어플리케이션 아키텍쳐이다.

Flux Architecture는 MVC 패턴의 문제점을 보완할 목적으로 고안되었다.

페이스북과 같은 대규모 어플리케이션에서는 MVC가 너무 복잡했다.

이 같은 문제의 대표적인 사례가 바로 페이스북의 안 읽은 글 갯수(unread count) 표시이다. 사용자가 읽지 않았던 글을 읽으면 읽지 않은 글 갯수에서 읽은 글 수만큼 빼면 되는 일견 단순해보이는 기능인데도, 페이스북 서비스에서 이를 MVC로 구현하기는 어려웠다고 한다. 어떤 글을 '읽음' 상태로 두면, 먼저 글을 다루는 thread 모델을 업데이트 해야하고 동시에 unread count 모델도 업데이트 해야한다. 대규모 MVC 애플리케이션에서 이 같은 의존성과 순차적 업데이트는 종종 데이터의 흐름을 꼬이게 하여 예기치 못한 결과를 불러일으킨다.

결국 페이스북 개발팀은 MVC를 버리고 다른 아키텍처를 적용하기로 한다.

그것이 바로 Flux이다.

Flux 데이터 흐름

참고 : https://velog.io/@pjj186/Redux

 

Redux 에 대해..

상태 관리를 도와주는 라이브러리이다.상위 컴포넌트의 State를 하위 컴포넌트로 전달 하고, 또 그 전달받은 하위컴포넌트가 그 State를 또 자신의 하위 컴포넌트에게 전달하고.. 이런식으로 계속

velog.io

 

 

리덕스 데이터 전달 방식은 아래 그림과 같다.

아래 데이터 전달 방식만 봐도 Redux를 사용하므로 얼마나 편리해지는지 알 수 있다.

 

Redux를 사용하지 않을 시, 컴포넌트의 깊이가 깊어질수록, 전달하는 과정이 점점 길어진다.

하지만 Redux를 사용하면, store에서 상태를 저장하고 필요시 꺼내서 쓰기 때문에

복잡한 로직을 사용하지 않아도 된다.


2. Redux 주요 개념

Action

  • 어떠한 이벤트, 동작
  • 객체형태
  • dispatch의 파라미터로 전달됨.
  • type 프로퍼티 필요
{
	type : 'ADD_TODO',
	data: {
		id: 1,
		text: '리덕스 액션1'
				}
}

 

Action Creator

  • 선택적으로 사용
  • 유지보수를 더 쉽게 하기 위해서.
export function addToro(data){
	return {
		type: "ADD_TODO",
		data
	}
}

 

Dispatch

  • 스토어의 내장함수 중 하나.
  • 액션 발생시킬떄 사용
  • 액션을 파라미터로 전달함.

Store

  • 한 어플리케이션 당 하나의 스토어 생성
  • 상태 저장

Reducer

  • 변화를 일으키는 함수
const initialState = {
	todo: [
		{
			id: 1,
			text: '할 일',
		},
		{
			id: 2,
			text: '할 일',
		},
	]
}

            // state가 undefined일 때는 initialState를 기본값으로 사용
function reducer(state = initialState, action) {
	switch (action.type) {
		case ADD_TODO:
			return {
				...state, // 불변성 유지 (spread 연산자 사용 예시)
				todo: state.todo.concat({
          id: action.id,
          text: action.text,
          isCompleted: false,
        }),
			};
		default: 
			return state;
		}
}

참고 :https://redux.js.org/tutorials/fundamentals/part-2-concepts-data-flow

 

Redux Fundamentals, Part 2: Concepts and Data Flow | Redux

The official Redux Fundamentals tutorial: learn key Redux terms and how data flows in a Redux app

redux.js.org

 


3. 리덕스는 언제 필요할까?

상태관리를 편하게 해주는 Redux, 무조건 적용해야될까?

“But it’s probably not going to be the best or most efficient tool at any of those use cases. Other tools like React Query or Apollo are much more specialized for this specific case of data fetching.”

⇒ 리덕스가 꼭 최선이 아닐수도 있다.

 

리덕스가 필요한 상황

  • 어플리케이션 내 여러 곳에서 사용해야될 state(상태)가 있을때
  • state가 자주 업데이트 될 때
  • 해당 state를 업데이트하는 로직이 복잡할 때
  • 큰 프로젝트로 많은 사람들과 공동작업을 진행할 때
  • 시간이 지남에 따라 state가 어떻게 업데이트 되는지 봐야될 때

참고: https://changelog.com/posts/when-and-when-not-to-reach-for-redux

 

When (and when not) to reach for Redux

I am a huge proponent of a couple of specific ideas. One is that you should always try to understand what problems a specific tool is trying to solve… And another is that you need to understand exactly what problems you are trying to solve in your own ap

changelog.com

 


4. Redux-Toolkit에 대해서

Redux Toolkit (줄여서 "RTK")은 Redux 로직을 작성하기 위해 Redux 공식적으로 추천하는 방법입니다.

Redux의 문제점 보완을 위해 등장

Redux의 문제점

  • 저장소 구성의 복잡성
  • 많은 패키지 필요성(의존성)
  • 한 작업 시 필요한 수 많은 코드양(boilerplate)

 

Redux-Toolkit 특징

  • Simple: 스토어 설정, 리듀서 생성, 불변성 업데이트 로직 사용을 편리하게 하는 기능 포함
  • Opitionated: 스토어 설정에 관한 기본 설정 제공, 일반적으로 사용되는 redux addon이 내장
  • Powerful : Immer에 영감을 받아 '변경'로직으로 '불변성'로직 작성 가능, state 전체를 slice로 자동으로 만들 수 있음
  • Effective : 적은 코드에 많은 작업을 수행 가능

 

참고 : 

(기존 redux 코드 vs redux toolkit 사용한 코드 정리가 잘 되어있음)

https://velog.io/@djaxornwkd12/Redux-Toolkit-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0

 

Redux Toolkit 알아보기

오늘은 리덕스 툴킷에 대해 알아보자~! Redux Toolkit이란 사용이유 Redux Toolkit은 Redux를 더 사용하기 쉽게 만들기 위해 Redux에서 공식 제공하는 개발도구이다. Redux Toolkit은 아래와 같은 Redux의 문제점

velog.io

 


4-1. Redux-Toolkit 폴더 구조

리덕스 공식문서에서 추천하는 폴더 구조

“Structure Files as Feature Folders with Single-File Logic
Redux itself does not care about how your application's folders and files are structured. However, co-locating logic for a given feature in one place typically makes it easier to maintain that code.
Because of this, we recommend that most applications should structure files using a "feature folder" approach (all files for a feature in the same folder). Within a given feature folder, the Redux logic for that feature should be written as a single "slice" file, preferably using the Redux Toolkit createSlice API. (This is also known as the "ducks" pattern). While older Redux codebases often used a "folder-by-type" approach with separate folders for "actions" and "reducers", keeping related logic together makes it easier to find and update that code.”

요약 하자면, 현재 리덕스는 기능 컴포넌트 파일과 Redux의 Slice파일을 함께 두는것을 추천한다.

참고 문서 : Redux 공식문서 

https://redux.js.org/tutorials/essentials/part-2-app-structure


4-2. Redux-Toolkit 사용법

configureStore.js

import { configureStore } from '@reduxjs/toolkit'
import usersReducer from '../features/users/usersSlice'
import postsReducer from '../features/posts/postsSlice'
import commentsReducer from '../features/comments/commentsSlice'

export default configureStore({
  reducer: {
    users: usersReducer,
    posts: postsReducer,
    comments: commentsReducer
  }
})

 

counterSlice.js

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
    }
  }
})

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

export default counterSlice.reducer

공식 문서에서

“You can only write "mutating" logic in Redux Toolkit's createSlice and createReducer because they use Immer inside! If you write mutating logic in reducers without Immer, it will mutate the state and cause bugs!”

⇒ 현재 redux-toolkit에서 제공하는 createSlice와 createReducer는 Immer라이브러리가 안에 사용되었기 때문에 불변성을 신경쓰지 않아도 된다!!!

 

> 옛날 Redux 코드 vs 현재 redux-toolkit의 createSlice사용

옛날 Redux 코드

function handwrittenReducer(state, action) {
  return {
    ...state,
    first: {
      ...state.first,
      second: {
        ...state.first.second,
        [action.someId]: {
          ...state.first.second[action.someId],
          fourth: action.someValue
        }
      }
    }
  }
}

 

현재 Redux-Toolkit 사용 후 코드

function reducerWithImmer(state, action) {
  state.first.second[action.someId].fourth = action.someValue
}

 

액션 사용 및 state 불러오기

import React, { useState } 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()
  const [incrementAmount, setIncrementAmount] = useState('2')

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

 

참고 :https://redux.js.org/tutorials/essentials/part-2-app-structure

 

Redux Essentials, Part 2: Redux Toolkit App Structure | Redux

The official Redux Essentials tutorial: learn the structure of a typical React + Redux Toolkit app

redux.js.org

 

반응형

댓글