LeeWang_31
이왕31
LeeWang_31
전체 방문자
오늘
어제
  • 분류 전체보기 (234)
    • 프로젝트 (2)
      • 사이드 프로젝트 (2)
      • Codestates_pre_project (0)
    • 프론트엔드 (169)
      • Html (19)
      • CSS (18)
      • JavaScript (29)
      • Codestates (76)
      • 코딩노트 (27)
    • 백엔드 (10)
      • node (10)
    • 구르는 돌 🌑 (16)
      • Codestates (11)
      • 생각 (4)
      • 공부 흔적 (1)
    • 정보 (18)
      • 오류노트 (2)
      • 인텔리제이 정보 (9)
      • 깃 정보 (3)
      • 기타 정보 (4)
      • 안드로이드스튜디오 정보 (0)
    • CS (7)
      • 이론공부 (7)
    • App (6)
      • Android (3)
      • Kotlin (3)
    • 컴퓨터 수학 (5)
      • 암호론 (5)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 코드스테이츠
  • 웹팩
  • figjam
  • linuix 코드스테이츠
  • 안드로이드스튜디오파이어베이스
  • UI/UX
  • 알고리즘
  • html
  • 안드로이드스튜디오범블비
  • JavaScript
  • 코딩애플
  • 파이어베이스연동
  • 2693
  • TODOlist
  • 사용자 친화 웹
  • React
  • 코플릿
  • ubuntu
  • 사용자친화웹
  • 사이드프로젝트
  • 2609
  • DP
  • css
  • codestate
  • linux
  • 1292
  • 백준
  • 자바스크립트
  • 생활코딩
  • 번들링

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
LeeWang_31

이왕31

[React] Redux
프론트엔드/Codestates

[React] Redux

2022. 11. 2. 17:22

코드스테이즈 41기 교육 내용을 정리하고 있습니다.
틀린 부분이 있으면 댓글로 알려주시면 감사하겠습니다.

 

Redux를 사용하는 이유

다음과 같은 컴포넌트가 있습니다.

Root은 최상의 컴포넌트이고, 각각의 컴포넌트의 위에 배치된 컴포넌트가 부모 컴포넌트 입니다

다음 그림 처럼 Right3컴포넌트에서 버튼을 눌러서 Left3의 숫자를 증가시키려고 하면 어떻게 코드를 작성해야 할까?

 

아마 가장 상위 컴포넌트인 Root컴포넌트에 const [number, setNumber] = useState(0);과 같이 useState를 선언한다.

Root 컴포넌트는 Left1컴포넌트에 useState의 값인 number를 props로 보내고,
Left1컴포넌트는 Left2컴포넌트에 useState의 값인 number를 props로 보내고,
Left2컴포넌트는 Left3컴포넌트에 useState의 값인 number를 props로 보내고,
Left3은 props로 받은 number를 출력한다.

마찬가지로,
Root 컴포넌트는 right1컴포넌트에 useState의 값을 변경하는 setNumber를 props로 보내고,
right1컴포넌트는 right2컴포넌트에 useState의 값을 변경하는 setNumber를 props로 보내고,
right2컴포넌트는 right3컴포넌트에 useState의 값을 변경하는 setNumber를 props로 보내고,
right3은 props로 받은 setNumber를 button의 onClick과 같이 사용하여 값을 변경한다.

단계가 3번만 되도 이렇게 복잡한데 100개 10000개라면 어떨까 !!

귀찮고 힘들뿐만 아니라, props를 중간에 안해줘서 값이 전달되지 않을수도 있습니다. 아주 큰일!

 

그래서  전역 상태를 관리할 수 있는 저장소를 제공하면서 이러한 문제를 해결할 수 있는 Redux에 대해 배워 보려고 합니다

npm redux

$ npm install redux react-redux

다음을 콘솔에 실행시켜 redux를 설치 합니다

 

Redux의 구조

gif 이쁘게 잘만든다

 

Redux는 다음과 같은 순서로 상태를 관리합니다.

  1. 상태가 변경되어야 하는 이벤트가 발생하면, 변경될 상태에 대한 정보가 담긴 Action 객체가 생성됩니다.
  2. 이 Action 객체는 Dispatch 함수의 인자로 전달됩니다.
  3. Dispatch 함수는 Action 객체를 Reducer 함수로 전달해줍니다.
  4. Reducer 함수는 Action 객체의 값을 확인하고, 그 값에 따라 전역 상태 저장소 Store의 상태를 변경합니다.
  5. 상태가 변경되면, React는 화면을 다시 렌더링 합니다.

즉, Redux에서는 Action → Dispatch → Reducer → Store 순서로 데이터가 단방향으로 흐르게 됩니다. 아래에서 Redux의 각각의 개념들을 코드 예시를 통해 좀 더 구체적으로 살펴보고, 단계별로 구현해보세요

Store

store는 상태가 관리되는 오직 하나뿐인 저장소의 역할을 합니다.
Redux의 state가 저장되어있는 공간입니다.

import { createStore } from 'redux';

const store = createStore(reducer)

 

createStore은 함수를 인자로 받는데, 다음 함수는 (여기서는 rootReducer) store안에 state를 어떻게 변경할지 정합니다.

이 내용은 바로 다음에 나옵니다.

 

Reducer

위어서 언급한 내용과 동일하게 store안에 state를 어떻게 변경할지 정합니다.

// store안에 state를 어떻게 변경할지
function reducer(currentState, action) {
    //초기값 설정
    if (currentState === undefined) {
        return {
            number: 1,
        }
    }
    const newState = {...currentState};
    if(action.type==='PLUS'){
        newState.number++;
    }
    return newState
}

함수 reducer의 인자는 초기값과 action으로 들어옵니다.

 

dispatch를 통해 전달받은 action의 타입을 if문이나 switch문과 같은 조건문으로 확인하고, 일치하면 상태를 변경합니다.

 

다음은 dispatch를 통해 PLUS라는 타입이 들어오면 객체의 number값을 증가시킵니다.

 

이떄 reducer은 순수 함수여야합니다.

외부 요인으로 인해 기대한 값이 아닌 엉뚱한 값으로 상태가 변경되는 일이 없어야 하기 때문입니다.

 

Action

말 그대로 어떤 액션을 취할 것인지 정해 놓은 객체이다

<input type="button" value="+" onClick={() => {
    dispatch({type:'PLUS'})
}}></input>

다음은 버튼이 눌리는 경우 dispatch를 통해 액션 타입을 보낸다.

여기서 action은 {type:'PLUS'}이다.

 

Dispatch

Dispatch는 Reducer로 Action을 전달해주는 함수입니다. Dispatch의 전달인자로 Action 객체가 전달됩니다.

<input type="button" value="+" onClick={() => {
    dispatch({type:'PLUS'})
}}></input>

 

Redux Hooks

Redux Hooks는 React-Redux에서 Redux를 사용할 때 활용 할 수 있는 Hooks메서드를 제공합니다.

그중 useSelector(), useDispatch()에 대해 배워 봅니다 

 

import {Provider, useSelector, useDispatch} from "react-redux";

상단에 다음과 같이 훅들을 import하여 사용합니다.

 

function reducer(currentState, action) {
    //초기값 설정
    if (currentState === undefined) {
        return {
            number: 1,
        }
    }
    const newState = {...currentState};
    if(action.type==='PLUS'){
        newState.number++;
    }
    return newState
}
const store = createStore(reducer);

모든 예제코드는 다음 reducer, store을 사용합니다.

 

useDispatch()

useDispatch()는 Action객체를 Reducer로 전달해 주는 Dispatch함수를 반환하는 메서드 입니다.

 

코드를 보겠습니다.

function Right3() {
    const dispatch = useDispatch()
    return (
        <div>
            <h1>Right3</h1>
            <input type="button" value="+" onClick={() => {
                dispatch({type:'PLUS'})
            }}></input>
        </div>
    );
}

dispatch라는 변수는 useDispatch()를 받고 있습니다.

button이 onClick이 되었을때, dispatch변수에 action객체인 {type:'PLUS'}를 전달합니다.

 

실행 이후 reducer은 다음 Action을 받게 되고, if문에 action type이 일치하기 때문에 newState.number은 값이 증가 하게 되고, 이 값을 store에 저장합니다.

 

useSelector()

useSelector()은 컴포넌트와 state를 연결하여 Redux의 state에 접근할 수 있게 해주는 메서드 입니다.

 

코드를 보겠습니다.

function Left3() {
    const number = useSelector((state)=>state.number)
    return (
        <div>
            <h1>Left3 : {number}</h1>
        </div>
    );
}

number라는 변수는 useSelector을 받는데, useSelect에는 함수가 들어가 있습니다.

(state)=>state.number 다음과 같은 형식으로 상태 값을 가져올수 있다.

state가 객체형식이 아니라면 (state)=>state,
객체 형식인데 id에 접근하고 싶다면 (state)=>state.Id ,,,

다음 number은 store에 저장되어있는 state.number에 접근하여 보여줍니다.

 

Provider

Hooks에 포함되진 않지만 같이 import하는 친구니까 한번 언급하려고 합니다.

 

Provider는 react-redux 라이브러리에 내장되어 있는 리액트 앱에 store를 쉽게 연동 할 수 있도록 도와주는 컴포넌트 입니다.

 

Provider에 연동할 컴포넌트를 감싸주고, Provider에 props로 store 값을 설정하면 됩니다.

export default function App() {

    return (
        <div id="container">
            <h1>Root</h1>
            <div id="grid">
                <Provider store={store}>
                    <Left1></Left1>
                    <Right1></Right1>
                </Provider>
            </div>
        </div>
    );
}

Provider이 Left1컴포넌트와 Right1 컴포넌트를 감싸고 있다.

두 컴포넌트와 하위 컴포넌트들은 react-redux 라이브러리를 사용할 수 있게 된다.

 

Provider에 store={store}을 하지 않으면 getState오류가 나기 때문에 반드시 값을 다음과 같이 설정 해줘야 한다.

오류명 : Uncaught TypeError: Cannot read properties of undefined (reading 'getState')

 

Redux의 세가지 원칙

1. Single source of truth

동일한 데이터는 항상 같은 곳에서 가지고 와야한다는 의미입니다.

즉, Redux에는 데이터를 저장하는 Store라는 단 하나뿐인 공간이 있음과 연결이 되는 원칙 입니다.

 

2. State is read-only

상태는 읽기 전용이라는 뜻으로, React에서 상태 갱신함수로만 상태를 변경할 수 있었던 것처럼, Redux의 상태도 직접 변경할 수 없음을 의미합니다.

즉, Action객체가 있어야만 상태를 변경할 수 있음과 연결되는 원칙입니다.

3. Changes are made with pure functions

변경은 순수함수로만 가능하다는 뜻으로, 상태가 엉뚱한 값으로 변경되는 일이 없도록 순수함수로 작성되어야하는 reducer와 연결되는 원칙입니다.


참조

  • https://redux.vlpt.us/1-8-provider.html
  • https://phsun102.tistory.com/85
  • https://www.youtube.com/watch?v=yjuwpf7VH74

 

저작자표시 (새창열림)

'프론트엔드 > Codestates' 카테고리의 다른 글

[사용자 친화 웹] Semantic HTML  (0) 2022.11.07
[사용자 친화 웹] 웹 표준 개념  (0) 2022.11.07
[React]Custom Component - Styled Components  (0) 2022.11.01
[사용자 친화 웹] 카카오톡 UX 분석  (0) 2022.10.26
[React] 빈 폴더에서 리액트 시작 (+ express)  (0) 2022.10.26
    '프론트엔드/Codestates' 카테고리의 다른 글
    • [사용자 친화 웹] Semantic HTML
    • [사용자 친화 웹] 웹 표준 개념
    • [React]Custom Component - Styled Components
    • [사용자 친화 웹] 카카오톡 UX 분석
    LeeWang_31
    LeeWang_31
    이왕 할 거면 기분 좋게

    티스토리툴바