[Web KIT640] Day 16. React - Redux ๐ŸŒบ

vincaยท2023๋…„ 2์›” 15์ผ
0

๐Ÿ‰ Web Frontend

๋ชฉ๋ก ๋ณด๊ธฐ
19/22

Introduction

Redux์— ๋Œ€ํ•ด์„œ ๋ฐฐ์›Œ๋ณด์ž. ๋ฐ”๋กœ ๊ณ ๊ณ ! ๐Ÿ™‹๐Ÿปโ€โ™‚๏ธ

๊ธฐ์กด์˜ ๋ฌธ์ œ์ 

Redux๋ฅผ ์“ฐ์ง€์•Š์œผ๋ฉด ์–ด๋–ค ๋ฌธ์ œ์ ์ด ์žˆ์„๊นŒ?

  • redux๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด props๋ฅผ ํ†ตํ•ด์„œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋„˜๊ฒจ์ฃผ์–ด์•ผ ํ•จ.
  • ๋˜ํ•œ ๊ฐ’์„ ๋ณ€๊ฒฝํ• ๋•Œ๋„ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ „๋‹ฌํ•ด์ฃผ์–ด ์‚ฌ์šฉํ•ด์•ผ๋งŒ ํ–ˆ๋‹ค.

์ •๋ฆฌํ•˜์ž๋ฉด, Propsํ˜•ํƒœ๋กœ State๋ฅผ ์ง์ ‘ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์—๊ฒŒ ๋„˜๊ฒจ์„œ ์‚ฌ์šฉํ•จ. ๊ทธ๊ฑธ ๋˜ ๋„˜๊ธฐ๊ณ ...๋„˜๊ธฐ๊ณ ..
๐Ÿ‘‰๐Ÿป ๋„ˆ๋ฌด๋‚˜ ๋ณต์žกํ•˜๊ณ  ๋ถˆํŽธํ•จ..

ํ•ด๊ฒฐ ๋ฐฉ์•ˆ

๊ทธ๋Ÿผ Redux๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด?

Redux์˜ STORE๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ๋˜๋ฉด ์ง์ ‘์ ์œผ๋กœ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๊ณ , ๋ณ€๊ฒฝ ๋˜ํ•œ STORE์— ์š”์ฒญํ•ด์„œ ์žฌ ๋žœ๋”๋ง ๊ฐ€๋Šฅํ•˜๊ธฐ์— ์œ„์˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

DAO๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด ๋†“๊ณ  ํŠน์ • ๊ธฐ๋Šฅ์„ ์š”์ฒญํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฐฉ์‹์„ ์ƒ๊ฐํ•˜๋ฉด ์‰ฝ๋‹ค.

DAO๋ž€?
DAO (Data Access Object)

  • DB์˜ data์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ์ฒด.
  • DB์— ์ ‘๊ทผํ•˜๋Š” ๋กœ์ง์„ ๋ถ„๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค.
  • MVC ํŒจํ„ด์—์„œ์˜ Model์˜ ์—ญํ• .

๊ทธ๋ž˜์„œ Redux ๋˜ํ•œ DAO๋ž‘ ๋™์ผํ•˜๋‹ค.

์ง์ ‘ DB์— ์ ‘๊ทผํ•˜์—ฌ data๋ฅผ ์‚ฝ์ž…, ์‚ญ์ œ, ์กฐํšŒ ๋“ฑ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

์ปดํฌ๋„ŒํŠธ์˜ ์ƒํƒœ๊ฐ€ ๋ณ€ํ•˜๋ฉด ๋ณ€๊ฒฝ๋œ ์ƒํƒœ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค์‹œ ๊ทธ๋ ค์ง€๋„๋ก ํ•˜๋Š” ๊ฒƒ.

๐Ÿ‘‰ Redux !

์ž ์ด์ œ Redux์— ๋Œ€ํ•ด์„œ ๋ณธ๊ฒฉ์ ์œผ๋กœ ์‚ฌ์šฉํ•ด๋ณด๊ณ  ์•Œ์•„๋ณด์ž.


Redux

  • ์ปดํฌ๋„ŒํŠธ ์ƒํƒœ๋ฅผ ํ•˜๋‚˜์˜ ์ €์žฅ์†Œ์ธ Store๋ฅผ ์ด์šฉ.
  • ์ณฌ๊ณ„์ ์œผ๋กœ ์ƒํƒœ๊ด€๋ฆฌ ๊ฐ€๋Šฅ.
  • Store์˜ ํŠน์ • ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด, ๊ด€๋ จ๋œ ์ปดํฌ๋„ŒํŠธ์— ์ ์šฉ๋  ์ˆ˜ ์žˆ๋„๋ก ์ฒ˜๋ฆฌํ•œ๋‹ค.

์‚ฌ์‹ค state์— ์ง์ ‘ ์ ‘๊ทผ์ด ์•„๋‹ˆ๋ผ ์‚ฌ์‹ค ๋ฉ”์†Œ๋“œ์— ์ ‘๊ทผํ•˜๋Š” ํ˜•์‹์ด๋‹ค. (@getter @setter ๋Š๋‚Œ)

Redux์˜ ์žฅ์ 

์˜ˆ์ธก ๊ฐ€๋Šฅ

Redux๋Š” ์ผ๊ด€๋˜๊ฒŒ ์ž‘๋™ํ•˜๊ณ  ๋‹ค์–‘ํ•œ ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰๊ฐ€๋Šฅํ•˜๋‹ค.

์ค‘์•™ ์ง‘์ค‘์‹

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ƒํƒœ์™€ ๋…ผ๋ฆฌ๋ฅผ ์ค‘์•™์œผ๋กœ ์ง‘์ค‘ํ™” ํ•˜๋ฉฐ ์‹คํ–‰์ทจ์†Œ/๋‹ค์‹œ ์‹คํ–‰, ์ƒํƒœ ์ง€์†์„ฑ๋“ฑ๊ณผ ๊ฐ™์€ ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

๋””๋ฒ„๊น… ๊ฐ€๋Šฅ

devTools๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ƒํƒœ๊ฐ€ ์–ธ์ œ, ์–ด๋””์„œ, ์™œ, ์–ด๋–ป๊ฒŒ ๋ณ€๊ฒฝ๋˜์—ˆ๋Š”์ง€ ์‰ฝ๊ฒŒ ์ถ”์ ํ•  ์ˆ˜ ์žˆ๋‹ค.
Redux์˜ ์•„ํ‚คํ…์ฒ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ๊ธฐ๋กํ•˜๊ณ  ์™„์ „ํ•œ ์˜ค๋ฅ˜ ๋ณด๊ณ ์„œ๋ฅผ ์„œ๋ฒ„์— ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Œ.

์œ ์—ฐ์„ฑ

Redux๋Š” ๋ชจ๋“  UI๊ณ„์ธต์—์„œ ์ž‘๋™ํ•˜๋ฉฐ ์‚ฌ์šฉ์ž์˜ ์š”๊ตฌ์‚ฌํ•ญ์— ๋งž๋Š” ๋Œ€๊ทœ๋ชจ ์• ๋“œ์˜จ ์—์ฝ”์‹œ์Šคํ…œ์„ ๊ฐ–์ถ”๊ณ  ์žˆ์Œ.

Redux์˜ 4๊ฐ€์ง€ ํ–‰๋™

Action

  • ์–ด๋–ค ์ž‘์—…์„ ํ•  ๊ฑด์ง€ ๊ตฌ๋ถ„ ํ•ด์ค€๋‹ค.
  • Object ํ˜•ํƒœ๋กœ flag๋ฅผ ํ•จ๊ป˜ Reducer๋กœ ์ „์†กํ•œ๋‹ค.
  • ๋ฐ์ดํ„ฐ๋˜ํ•œ ํ•จ๊ป˜ ๋ณด๋ƒ„.

Reducer

  • Action์—๊ฒŒ ๋ฐ›์€ object๋กœ, ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๋“ค์ด ๊ณต์œ  ํ•  ์ˆ˜ ์žˆ๋Š” state์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•œ๋‹ค.
  • setState์˜ ์—ญํ• (setter ์—ญํ• )

Store

  • ์ƒํƒœ๋ฅผ ๊ณ„์† ํ™•์ธ ํ•˜๊ณ  ๋ณ€๊ฒฝ๋œ ์‚ฌํ•ญ์„ View์—๊ฒŒ ์•Œ๋ ค ์คŒ.
  • ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚˜๋ฉด Component๋Š” ์ž๋™ ๊ฐฑ์‹  ๋จ์œผ๋กœ Reducer๋ฅผ Store์— ์ ์šฉ ์‹œ์ผœ์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋จ.
  • ๋Œ€๋ถ€๋ถ„์˜ ๋ณต์žกํ•œ ๋ถ€๋ถ„์€ Store์— ์žˆ์œผ๋ฏ€๋กœ Store๋งŒ ๋ณด๋ฉด ๋œ๋‹ค.

View

  • ์ปดํฌ๋„ŒํŠธ๋ฅผ ์˜๋ฏธ

์ž ๊ทธ๋Ÿผ ์‹ค์Šต์„ ํ†ตํ•ด ์‹ค์ œ๋กœ ์‚ฌ์šฉํ•ด๋ณด์ž!


์‹ค์Šต

Redux ์„ค์น˜

npm install redux --save
npm install react-redux --save
npm install @reduxjs/toolkit react-redux

์งง๊ฒŒ ์“ด๋‹ค๋ฉด..(์œ„ ์ฝ”๋“œ์™€ ๋™์ผํ•˜๋‹ค)

npm i redux -S
npm i react-redux -S
npm i @reduxjs/toolkit react-redux

์†Œ์Šค์ฝ”๋“œ ์ž‘์„ฑ

Controller์—์„œ๋Š” index์˜ Redux๋ฅผ ์ œ์–ด
์—ฌ๊ธฐ์„œ dispatch๋ฅผ ํ†ตํ•ด์„œ Redux๋ฅผ ์ œ์–ด
app.js์—์„œ๋Š” index.js์˜ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด
useSelector๋ผ๋Š” ๋ถ€๋ถ„์œผ๋กœ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ๊ฐ์ง€ํ•˜๊ณ  ์žฌ ๋žœ๋”๋งํ•จ.
Controller์—์„œ ๋””์ŠคํŒจ์น˜์—์„œ ํ˜ธ์ถœํ•  ๋•Œ index.js์˜ reducer๋ฅผ ๋ฐ›์•„์™€์„œ ์”€
index.js๊ฐ€ ์ œ์ผ ์ตœ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์ด๋ฏ€๋กœ index.js์—๋‹ค๊ฐ€ redux๋ฅผ ์„ค์ •ํ•˜๊ณ  ์—ฌ๊ธฐ์— ์žˆ๋Š” reducer์™€ State๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

index js์— ์ •์˜

// react-redux ๊ด€๋ จ ๋ชจ๋“ˆ import
import {Provider} from "react-redux"
import { legacy_createStore as createStore } from 'redux';

์—ฌ๊ธฐ์„œ๋Š” ๋ณ„๋ช… (Alias)๋ฅผ ํ†ตํ•ด createStore๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ๋‹ค.

CurrentState

//ํ•„์š”ํ•œ State๋“ค์„ ์ง‘์–ด ๋„ฃ์–ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
const currentState = {count : 1};

์ด๋ฅผ ๊ด€๋ฆฌํ•ด ์ฃผ๋Š” getter/setter๊ฐ€ ํ•„์š”ํ•œ๋ฐ ์ด๋ฅผ ๊ด€๋ฆฌํ•ด ์ฃผ๋Š” ๊ฒƒ์ด ๋ฐ”๋กœ reducer์ด๋‹ค.

reducer

function reducer(state = currentState, action) {
  // ๋งŒ์•ฝ ๊ฐ’์ด ์ •์˜๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด ๊ฐ’์„ ๋„ฃ์–ด์ค€๋‹ค.
  if(currentState == undefined) {
    return {count : 10};
  }
  // State๋ฅผ ๋ณ€๊ฒฝ
  if(action.type == 'count์ฆ๊ฐ€') {
    state.count++;
  }
  if(action.type == 'count๊ฐ์†Œ') {
    state.count--;
  }
  // ์ƒˆ๋กœ์šด State๋ฅผ ๋งŒ๋“ค์–ด์„œ ๋ฐ˜ํ™˜
  const newState = {...state}
  return newState;
}

createStore๋ฅผ ํ†ตํ•ด์„œ reducer๋ฅผ store๋กœ ์ƒ์„ฑํ•ด์ค€๋‹ค.

Store ์ƒ์„ฑ

let store = createStore(currentState);

์ด์ œ app.js์ชฝ์œผ๋กœ ๋„˜์–ด๊ฐ€๋ณด๋„๋ก ํ•˜์ž.


App.js์— ์ •์˜

import { useSelector } from 'react-redux';

์ผ๋‹จ ์„ ์–ธ๋œ State์ธ count๊ฐ’์„ index.js์—์„œ ํ•˜๋‚˜ ๊ฐ€์ ธ์™€ ๋ณผ ๊ฒƒ์ด๋ฏ€๋กœ redux์—์„œ useSelector๋ฅผ ์„ ์–ธํ•œ๋‹ค.

useSelect ์‚ฌ์šฉ

  // ์ฝœ๋ฐฑํ•จ์ˆ˜๋กœ ๋งŒ๋“ค์–ด์ค€๋‹ค state๋ฅผ useselector์—์„œ ๋ฐ›์•„์„œ ๊ฐ’์„ ๊ฐ€์ ธ์˜ด
  const count = useSelector((state)=>{
    return state.count;
  })
  
  // ๋ฆฌํ„ด๋˜๋Š” ๋ถ€๋ถ„
  return(
      <div>
    <h1>React Redux Programing</h1>
    <p>count : {count}</p>
	</div>
)

๊ฐ’์ด ์ž˜ ๋‚˜์˜ค๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

dispatch ์‚ฌ์šฉ(๊ฐ’ ๋ณ€๊ฒฝ)

์ด์ œ dispatch๋ฅผ ์‚ฌ์šฉํ•ด๋ณด์ž.
useSelector๋Š” ๊ฐ’์„ ์ฐธ์กฐํ• ๋•Œ ๊ฐ’์„ ๋ณ€๊ฒฝํ• ๋•Œ๋Š” useDispatch๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

๋จผ์ € dispatch ์‚ฌ์šฉ์„ ์œ„ํ•ด useDispatch๋ฅผ ํ†ตํ•ด dispatch๋ฅผ ํ•˜๋‚˜ ์ƒ์„ฑํ•˜์ž.

// import๋ฌธ์—๋‹ค๊ฐ€ ์ถ”๊ฐ€
import { useSelector, useDispatch } from 'react-redux';
//  dispatch ๊ฐ์ฒด ์ƒ์„ฑ - ํ•จ์ˆ˜์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•จ
const dispatch = useDispatch();

๋ฆฌํ„ด๋ฌธ์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

  return (
    <div>
    <h1>React Redux Programing</h1>
    <p>count : {count}</p>
    <p>
        <button onClick={()=>{
          dispatch({type:'count์ฆ๊ฐ€'})
        }}>
          ์ฆ๊ฐ€
        </button>
        <button onClick={()=>{
          dispatch({type:'count๊ฐ์†Œ'})
        }}>
          ๊ฐ์†Œ
        </button>
    </p>
    </div>
  );

๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฒ„ํŠผ์„ ํ†ตํ•ด ์ฆ๊ฐ€์™€ ๊ฐ์†Œ๊ฐ€ ์ด๋ฃจ์–ด์ง€๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์ปดํฌ๋„ŒํŠธ ๋ถ„๋ฆฌ

๋„ˆ๋ฌด ์†Œ์Šค์ฝ”๋“œ๊ฐ€ ๋‚œ์žกํ•ด์งˆ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ด์ฏค์—์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ชจ๋“ˆํ™”ํ•˜์ž.

View.js๋ฅผ ํ•˜๋‚˜ ์ƒ์„ฑํ•ด์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋งŒ๋“ค์–ด์ค€๋‹ค.

import { useDispatch, useSelector } from 'react-redux';

function StateView(){
    const count = useSelector((state)=> {
        return state.count;
    });
    const age = useSelector((state)=> {
        return state.age;
    });
    return(
        <>
        <p>count : {count}</p>
                <p>age : {age}</p>
        </>
    
        )
}
export default StateView;

Github

You can access to whole source code right Here!

profile
๋ถ‰์€ ๋ฐฐ ์˜ค์ƒ‰ ๋”ฑ๋‹ค๊ตฌ๋ฆฌ ๊ฐœ๋ฐœ์ž ๐ŸฆƒCloud & DevOps

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