[Redux]리덕스란?

Hyoyoung Kim·2024년 2월 25일
0

React TIL

목록 보기
37/40

➡️ Redux란?

리액트 상태 관리 라이브러리입니다. 리덕스를 사용하면 컴포넌트의 상태 업데이트 관련 로직을 다른 파일로 분리시켜서 더욱 효율적으로 관리할 수 있습니다.

➡️ Redux 개념

1. 액션(action)

  • 상태에 어떠한 변화가 필요하면 액션이란 것이 발생합니다.
  • 하나의 객체로 표현되고 액션 객체는 type 필드를 반드시 가지고 있어햐 한다. 이 값을 액션의 이름이라고 생각하면 된다. 그 외의 값들은 나중에 상태 업데이트를 할 떄 참고해야할 값이다.
  • 액션 이름은 문자열 형태로, 주로 대문자로 작성하며 액션 이름은 고유해야 합니다. 이름이 중복되면 의도하지 않은 결과가 발생할 수 있기 때문이다.

2. 액션 생성 함수(action creator)

  • 액션 객체를 만들어 주는 함수이다.
  • 어떤 변화를 일으켜야 할 떄마다 액션 객체를 만들어야 하는데 매번 액션 객체를 직접 작성하는 것이 번거로우니 함수를 만들어서 관리한다.

3. 리듀서(reducer)

  • 변화를 일으키는 함수이다.
  • 액션을 만들어서 발생시키면 리듀서가 현재 상태와 전달 받은 액션 객체를 파라미터로 받아온다. 두 값을 참고하여 새로운 상태를 만들어서 반환해 준다.

4. 스토어(store)

  • 한개의 프로젝트는 단하나의 스토어만 가질 수 있다.
  • 스토어 안에는 현재 애플리케이션 상태와 리듀서가 들어가 있으며, 그 외에도 여러 내장 함수를 지닌다.

✔️ store 메서드

1. getState()

  • 애플리케이션의 현재 상태를 반환합니다.

2. dispatch(action)

  • 액션을 보냅니다. 상태 변경을 일으키는 메서드입니다.
  • 여기서 action은 액션객체를 뜻합니다.

3. subscribe(listener)

  • 상태가 업데이트될때마다 호출되는 listener함수를 상태가 바뀔때마다 호출합니다.

4. replaceReducer(nextReducer)

  • 현재 스토어에서 상태를 계산하기 위해 사용중인 리듀서를 교체합니다.
  • 이것은 고급 api로 코드분할이나 동적으로 리듀서를 불러오고 싶을 떄 사용할 수 있습니다.

5. 디스패치(dispatch)

  • 스토어의 내장 함수 중 하나이다. 디스패치는 액션을 발생시키는 것이라고 이해하면 된다.
  • 이 함수는 dispatch(action)과 같은 형태로 액션 객체를 파라미터로 넣어서 호출한다. 이 함수가 호출되면 스토어는 리듀서 함수를 실행시켜서 새로운 상태를 만들어 준다.

6. 구독(subscribe)

  • 스토어의 내장 함수 중 하나이다.
  • subscribe 함수 안에 리스너 함수를 파라미터로 넣어서 호출해주면, 이 리스너 함수가 액션이 디스패치되어 상태가 업데이트될 때마다 호출된다.

➡️ Redux 흐름

1. 초기 코드

//index.css
.toggle{
    border : 2px solid black;
    width: 64px;
    height: 64px;
    border-radius: 32px;
    box-sizing: border-box;
}

.toggle.active{
    background: yellow;
}


// index.html
<html>
    <head>
        <link rel="stylesheet" type="text/css" href="index.css"/>
    </head>
    <body>
        <div class="toggle"></div>
        <hr/>
        <h1>0</h1>
        <button id="increase">+1</button>
        <button id="decrease">-1</button>
        <script src="./index.js"></script>
    </body>
</html>

2. 액션 타입과 액션 생성함수 및 초기값 설정

//index.js

//DOM레퍼런스
const divToggle = document.querySelector('.toggle');
const counter = document.querySelector('h1');
const btnIncrease=document.querySelector('#increase');
const btnDecrease = document.querySelector('#decrease');

//액션타입
const TOGGLE_SWITCH ='TOGGLE_SWITCH';
const INCREASE = 'INCREASE';
const DECREASE = 'DECREASE';

//액션 생성함수
const toggleSwitch = ()=>({type : TOGGLE_SWITCH})
const increase = difference=>({type:INCREASE,difference})
const decrease = ()=>({type:DECREASE})

//초기값 설정
const initialState={
    toggle : false,
    counter:0
}

3. reducer 함수 정의

  • 리듀서 함수가 맨 처음 호출되 때는 state 값이 undefined이다. 해당 값이 undefined로 주어졌을 때는 initalState를 기본값으로 설정하기 위해 함수의 파라미터 쪽에 기본값이 설정되어 있다.
  • 리듀서에서는 상태의 불변성을 유지하면서 데이터에 변화를 일으켜야 한다.
//index.js

//state가 undefined일때는 initialState를 기본값으로 사용
function reducer(state= initialState, action){
  //action.type에 따라 다른 작업을 처리함
    switch(action.type){
        case TOGGLE_SWITCH: 
            return{
                ...state, //spread 연산자를 활용해 불변성 유지 필요
                toggle:!state.toggle
            };
        case INCREASE:
            return{
                ...state,
                counter: state.counter + action.difference
            };
        case DECREASE:
            return{
                ...state,
                counter:state.counter-1
            };
            default:
                return state;
    }
}

4. store 만들기

//index.js

import {createStore} from 'redux';

(...)
 
 const store = createStore(reducer);

🧐 import한 redux createStore에 그어진 밑줄

이렇게 작성하였더니 아래와 같이 createStore에 밑줄이 그어져 있다.

그래서 redux 공식 문서 가보니 아래와 같이 써져있는데 해석하자면

  • 지원 중단으로 인해 가져오고 사용할 때 시각적 취소선이 표시됩니다.createStore, 그러나 런타임 오류나 경고는 없습니다 .
  • createStore계속해서 무기한으로 작동하며 제거되지 않습니다 . 그러나 오늘날 우리는 모든 Redux 사용자가 모든 Redux 로직에 Redux Toolkit을 사용하기를 원합니다
  • 취소선을 보고 싶지 않다면 3가지 방법이 있다.
  1. RTK configureStore을 쓰거나
  2. 아무것도하지 마세요. 이는 시각적인 취소선일 뿐이며 코드 작동 방식에는 영향을 주지 않습니다. 그냥 무시하세요
  3. 아래와 같은 코드로 쓰면 취소선이 안보인다.
import { legacy_createStore as createStore } from 'redux'

➡️ 그래서 나는 3번째 방법을 쓰기로 했다.

5. render 함수

render이란 함수는 상태가 업데이트 될때마다 호출되며, 리액트의 render 함수와는 다르게 이미 html을 사용하여 만들어진 ui의 속성을 상태에 따라 변경해준다. 즉, 브라우저, 화면에 페인트한다는 소리..

//index.js

const render=()=>{
  //현재 상태를 불러오는 store 메서드
    const state = store.getState(); 
    if(state.toggle){
      //toggle이 참이라면, 클래스 이름을 추가한다.
        divToggle.classList.add('active'); /
    }else{
      //toggle이 거짓이라면 클래스 이름을 제거한다.
        divToggle.classList.remove('active');
    }
    //counter의 text를 state.counter로 바꿔준다.
    counter.innerText =state.counter
}

render()

6. subscribe

  • subscribe를 사용하여 스토어의 상태가 바뀔 때마다 위에 만든 render함수가 호출되도록 해준다.
  • subscribe 함수의 파라미터로는 함수 형태의 값을 전달한다. 전달된 함수는 추후 액션이 발생하여 상태가 업데이트될때마다 호출된다.
//index.js
store.subscribe(render)

7. dispatch

  • 액션을 발생시키는 것을 디스패치라고 한다.
  • 디스패치를 할때는 스토어의 내장 함수 dispatch를 사용합니다.
  • 파라미터는 액션객체를 넣어주면됩니다.
//index.js


divToggle.onclick =()=>{
    store.dispatch(toggleSwitch());
}

btnIncrease.onclick=()=>{
    store.dispatch(increase(1))
};

btnDecrease.onclick=()=>{
    store.dispatch(decrease())
}

➡️ Redux의 3가지 규칙

1. 단일 스토어

  • 하나의 애플리케이션 안에는 하나의 스토어가 들어가 있습니다.
  • 여러개의 스토어를 사용하면 상태 관리가 복잡해줄 수 있습니다.

2. 읽기 전용 상태(불변성 유지)

  • react의 setState를 state가 업데이트할때마다 객체나 배열을 업데이트하는 과정에서 불변성을 지켜줍니다.
  • 리덕스에서도 불변성을 지키기 위해 상태를 업데이트할때 기존 객체는 건드리지 않고 새로운 객체를 생성해 주어야 합니다.
  • 즉, 리덕스도 불변성을 지켜야 합니다.

3. 리듀서는 순수한 함수

  • 변화를 일으키는 리듀서 함수는 순수함수여야 합니다.
  • 순수 함수 조건
    • 리듀서 함수는 이전 상태액션 객체파라미터로 받습니다.
    • 파라미터 외의 값에는 의존하면 안됩니다.
    • 이전 상태는 절대로 건드리지 않고, 변화를 준 새로운 상태 객체를 만들어서 반환합니다.
    • 똑같은 파라미터로 호출된 리듀서 함수는 언제나 똑같은 결과 값을 반환해야 합니다.

0개의 댓글