React

Redux 리덕스 개념과 예제(JavaScript)

TASTY.K 2023. 4. 19. 07:23
반응형

리덕스(Redux)의 개념

리덕스 홈페이지

 

리덕스(Redux)란?

 

 

리덕스(Redux) 공식홈페이지에서는 리덕스를 자바스크립트 앱을 위한 예측 가능한 state 보관함("A predictable state container for JS App")으로 정의하고 있다. 여기서 state는 1개의 객체 변수(ex. {name: "홍길동", age: 26})를 의미한다. 다시 말해 리덕스는 {} 이렇게 생긴 한 개의 객체 안에 앱에서 다루는 모든 데이터를 우겨넣어 관리하는 역할을 하며, 그 객체를 state라고 부른다.

    리덕스는 리액트(React)를 효율적으로 사용하기 위해 발전되어 왔으나, 현재는 독립된 훌륭한 기능들을 갖추었으며 JavaScript 로 작성한 모든 앱에 적용 가능하다.

 

리덕스(Redux)의 작동 방식

 

생활코딩의 리덕스 강의에서는 아래 그림을 이용하여 리덕스의 작동 방식을 설명한다.

Copyright @생활코딩 https://opentutorials.org/course/4901/24935

 

리덕스는 말하자면 1개의 상태객체(state)와 1명의 서기관(reducer), 3명의 창구직원(dispatch, subscribe, getState)으로 구성된 1개의 스토어(store)이다. 1개 프로젝트에는 1개 스토어만 세울 수 있다.

 

작업 의뢰

웹사이트의 UI에서 이 리덕스 스토어에게 데이터 관련 작업 의뢰를 보내온다. 이때 "action"이라는 형식을 사용한다. 

 

의뢰 접수

작업의뢰는 창구직원들인 getState, dispatch, subscribe 세 사람이 나눠 접수한다. (속내용을 모르고 봉투 분류만 해서 리듀서에게 넘김)

  • getState 담당자: getState는 이름에서 알 수 있듯, state에 기록된 데이터 내용을 의뢰인에게 알려주는 역할을 한다.
  • dispatch 담당자: 그리고 dispatch는 데이터를 추가, 수정, 삭제하는 역동적인 작업에 대한 의뢰를 접수하며,
  • subscribe 담당자: 이때 subscribe는 state가 바뀌었음을 관련된 주주 컴포넌트들에게 통보하는 일을 한다. (바뀐 내용 반영해서 다시 렌더링 하시라고..)

 

작업 수행

상태객체(state)에 접근할 수 있는 사람은 오직 리듀서(reducer)라는 서기관 뿐이다.

  • 이분이 창구직원으로부터 전달받은 action 봉투를 열어서 적힌대로 연산하고, 결과에 따라 state 데이터를 쓰거나 지우거나 고치는 작업을 수행한다.
  • 연산식들은 이미 리듀서님 몸에 백과사전처럼 장착되어 있다. '어떤 값'에 '무슨 연산'을 적용할지만 알면 된다
  • 그 '어떤 값'은 리듀서가 이미 알고 있는 기존의 state 객체 안 데이터이고
  • 그 '무슨 연산'인지 알려주는 놈은 전달된 action 봉투 안에 들어 있는 type 이란 놈이다(실제로는 action.type == 'CHANGE_COLOR' <-이렇게 생김)
  • 이래서.. 리듀서님은 연산실로 가실 때 항상 state와 action을 매개변수로 끼고 들어간다(function reducer(state, action)... <-이렇게)
  • 연산식이 이미 장착되어 있다는 점에서 "예측가능한(predictable)"이란 단어를 리덕스의 정의에 포함시킨 게 아닐까

 


리덕스(Redux) 사용법

 

설치하기

두가지 방법이 있다.

1) 하나는 리액트 개발자라면 익숙할 npm 방식,

# NPM
npm install redux

# Yarn
yarn add redux

2) 그리고 하나는 HTML 개발자라면 익숙할 CDN 방식이다. [REDUX CDN 출처]

<HTML>
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.2.1/redux.min.js" integrity="sha512-1/8Tj23BRrWnKZXeBruk6wTnsMJbi/lJsk9bsRgVwb6j5q39n0A00gFjbCTaDo5l5XrPVv4DZXftrJExhRF/Ug==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  </head>
  
  ......

 

 

JavScript + Redux 기본코드

 

1. 스토어 만들기

  • Redux.createStore() 로 store를 만든다
  • ()안에 매개변수로 reducer가 반드시 들어가야 한다.
  • 일단 reducer를 괄호 안에 써두고 잇따라 reducer 바로 작성
<script>
  var store = Redux.createStore(reducer);
</script>

 

2. 리듀서 작성

  • 연산할 내용을 리듀서에 탑재시켜주는 작업
<script>
// reducer에는 state과 action이 무조건 들어와야함
function reducer(state, action){
    // 1.1. 최초 1회 무조건 실행됨. 그때 state === undefined 임
    if(state === undefined){
        // 1.2. 따라서 이것은 초기값
        return {color:'yellow'}
    }
    // 2.1. state 복사해서 쓰려고 만든 변수(불변성 지키기)
    var newState;
    // 2.2. action.type이 'CHANGE_COLOR'라는 놈일 때...
    if(action.type === 'CHANGE_COLOR'){
        // 2.3.1. 새 변수에 {}요 형식 안에, state 복사해 넣고, 거기에 color 만 바꾸거나 추가해서 객체 만들어 얺음
        // 2.3.2. Object.assign이란 놈은 첫 변수에 데이터 타입, 두 번째 변수에 복사할 놈, 세 번째 변수에 추가하거나 수정할 데이터값 넣음
        newState = Object.assign({}, state, {color:action.color});
    }
    // 2.3. 새로 만든 state를 반환... 기존state가 업뎃됨
    return newState;
}

// 위에서 만들어준 놈
var store = Redux.createStore(reducer);
</script>

 

3. getState 사용하기

//기본형
store.getState();
// 사용 예제
function red() {
    // 1. store에 getState 호출 보내서 state 받아옴
    var state = store.getState();
    // 2. red라는 id를 가진 HTML 태그객체에 넣기 ${state.color}
    document.querySelector('#red').innerHTML = `
        <div class="container" id="component_red" style="background-color:${state.color}">
            <h1>red</h1>
        </div>
    `;
}

 

4. dispatch 사용하기

// 기본형
store.dispatch({type:'CHANGE_COLOR', color:'red'});
// 사용예제
function red() {
    ......
    document.querySelector('#red').innerHTML = `
        .......
            <h1>red</h1>
            // 3. dispatch로, 클릭하면 state.color를 red로 바꿔주는 기능 구현
            <input type="button" value="fire" onclick="
                store.dispatch({type:'CHANGE_COLOR', color:'red'});
            ">
        </div>
    `;
}

 

5. subscribe 달아주기

  • 아래와 같이 한 줄. subscribe() 매개변수로 state 변경시 실행될 함수명 던져주면 완료
store.subscribe(red);

 

* 생활코딩 Redux + JavaScript 코드 예제 전체 [출처]

<!DOCTYPE html>
<html>

<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.1/redux.js"></script>
</head>

<body>
    <style>
        .container {
            border: 5px solid black;
            padding: 10px;
        }
    </style>
    <div id="red"></div>
    <div id="blue"></div>
    <div id="green"></div>
    <script>
function reducer(state, action){
    console.log(state, action);
    if(state === undefined){
        return {color:'yellow'}
    }
    var newState;
    if(action.type === 'CHANGE_COLOR'){
        newState = Object.assign({}, state, {color:action.color});
    }
    return newState;
}
var store = Redux.createStore(reducer);
function red() {
    var state = store.getState();
    document.querySelector('#red').innerHTML = `
        <div class="container" id="component_red" style="background-color:${state.color}">
            <h1>red</h1>
            <input type="button" value="fire" onclick="
                store.dispatch({type:'CHANGE_COLOR', color:'red'});
            ">
        </div>
    `;
}
store.subscribe(red);
red();

function blue() {
    var state = store.getState();
    document.querySelector('#blue').innerHTML = `
        <div class="container" id="component_blue" style="background-color:${state.color}">
            <h1>blue</h1>
            <input type="button" value="fire" onclick="
                store.dispatch({type:'CHANGE_COLOR', color:'blue'});
            ">
        </div>
    `;
}
store.subscribe(blue);
blue();

function green() {
    var state = store.getState();
    document.querySelector('#green').innerHTML = `
        <div class="container" id="component_green" style="background-color:${state.color}">
            <h1>green</h1>
            <input type="button" value="fire" onclick="
                store.dispatch({type:'CHANGE_COLOR', color:'green'});
            ">
        </div>
    `;
}
store.subscribe(green);
green();

    </script>
</body>

</html>

 

반응형