Learning React(14. 리덕스 소개)

min seung moon·2021년 8월 17일
0

Learning React

목록 보기
14/15

1. 리덕스

01. 리덕스란 무엇인가?

  • 리덕스는 우리가 지금까지 배운 부분 중 애플리케이션 상태 관리와 매우 밀접한 관계를 갖고 있다
  • 리덕스는 어떠한 라이브러리나 프레임워크를 중요하게 생각하지 않는다, 리덕스는 오직 애플리케이션 상태를 다루고 저장하는 마법을 앱에 뷰여하는 일만 신경쓴다
  • 리덕스 세계에서는 모든 애플리케이션 상태를 스토어(Store)라고 하는 단일한 장소에 저장한다
  • 스토어로부터 데이터를 읽는 일은 쉬우나, 정보를 스토어에 저장하는 일은 완전히 다른 얘기다
    • 스토어에 새로운 상태 정보를 추가하거나 기존 상태를 변경하는 일은 무엇이 변경됐는지 기술하는 액션(action)과 그 액션의 결과로 최종 상태를 결정하는 리듀서(reducer)의 조합을 사용해 가능하다
  • 그림을 보면 데이터 하나 저장하는데 왜이렇게 번거롭게 우회하는거 같냐라고 느낄 수 있다
    • 그 이유는 확장성 때문이다
      • 아무리 간단한 앱이라도 애플리케이션의 상태 관리는 번거로운 일이다
      • 게다가 복잡한 앱에서는 서로 다른 부분에서 각자 애플리케이션의 상태에 접근하고 변경해야 할 수도 있다
      • 그러나 걱정할 필요는 없다, 간단한 앱이든 복잡한 앱이든 애플리케이션의 상태 저장을 쉽게 해주는 리덕스의 해법이 있기 때문이다
    • 그리고 리덕스는 애플리케이션의 상태를 예측 가능하도록 관리해준다
        1. 애플리케이션의 모든 상태는 하나의 장소에 저장된다, 즉 상태의 일부를 갱신하기 위해 다양한 데이터 저장소를 찾아 다니지 않아도 된다, 그리고 단일한 장소에 저장되기에 데이터의 정합성 문제도 걱정 없다
        1. 상태는 읽기 전용이며 오직 액션을 통해서만 변경된다, 스토어 안의 데이터를 변경할 수 있는 유일한 방법은 액션에 의존하는 것이다
        1. 반드시 마지막 상태가 지정돼야 한다, 쉽게 말하자면, 상태는 결코 수정되거나 변형되지 않는다, 따라서 반드시 리듀서를 사용해 마지막 상태를 지정해야 한다

02. 리덕스를 사용한 앱 제작

-1. 리덕스 셋팅

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Favorite Colors!</title>
  <script src="https://unpkg.com/redux@latest/dist/redux.js"></script>
</head>

<body>
  <script>
  </script>
</body>

</html>

-2. 리덕스 액션

  • 리덕스 라이브러리를 참조했으니 액션을 정의해보자
  • 액션만이 스토어와 통신하기 위한 유일한 메커니즘이라는 사실을 기억하자
  • 액션을 정의하는 방법은 자유롭다
    • 모든 액션 객체는 하나의 type 속성을 갖는다
    • type은 하고자 하는 작업을 나타내는 키워드다
    • type을 설정했다면 그 다음엔 어떤 정보든 원하는 대로 액션 안에 담을 수 있다
  • 이번에 생성한 addColor와 removeColor는 리덕스에서 액션 생성자라고 불린다
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Favorite Colors!</title>
  <script src="https://unpkg.com/redux@latest/dist/redux.js"></script>
</head>

<body>
  <script>
    function addColor(value) {
      return {
        type : "ADD"
        , color : value
      }
    }

    function removeColor(value) {
      return {
        type : "REMOVE"
        ,color : value
      }
    }
  </script>
</body>

</html>

-3. 리듀서

  • 액션이 하고자 하는 일을 정의한다면, 리듀서는 그게 무슨 일인지와 새로운 상태를 정의하는 방법을 구체적으로 다룬다
      1. 스토어의 원래 상태에 접근할 수 있게 한다
      1. 현재 발생된 액션을 조사할 수 있게 한다
      1. 스토어의 새로운 상태를 저장할 수 있게 한다
  • 먼저 state 값을 확인하고 state가 존재하지 않는다면 앱이 처음 구동됐을 때 처럼 상태 객체를 빈 배열로 초기화한다
  • 나머지는 액션을 다루는 코드로 리듀서가 액션 객체 자체를 인자로 받는다는 점에 주목해야 한다, 이는 액션의 type 속성분만 아니라 액션 안에 지정된 모든 정보에 접근할 수 있다는 의미이다
  • 리듀서 안에서 절대 하지 말아야 할 사항
      1. 받은 인자를 변형하며 안된다
      1. API 호출이나 라우팅 변경 등과 같은 추가 기능 구현을 해선 안된다
      1. Date.now()나 Math.random()과 같은 비순수 함수의 호출을 하지 말자
  • 그렇기에 리듀서에서도 Add시 push가 아닌 concat 함수를 통해서 새로운 배열을 반환하게 해준다 마찬가지로 Remove시에도 filter 함수를 통해서 새로운 배열을 반환한다
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Favorite Colors!</title>
  <script src="https://unpkg.com/redux@latest/dist/redux.js"></script>
</head>

<body>
  <script>
    function addColor(value) {
      return {
        type: "ADD",
        color: value
      }
    }

    function removeColor(value) {
      return {
        type: "REMOVE",
        color: value
      }
    }

    function favoriteColors(state, action) {
      if (state === undefined) {
        state = [];
      }

      if (action.type === "ADD") {
        return state.concat(action.color);
      } else if (action.type === "REMOVE") {
        return state.filter(item => item !== action.color)
      } else {
        return state;      }
    }
  </script>
</body>

</html>

-4. 스토어

  • 남은 건 액션과 리듀서를 스토어에 엮는 일이다
  • 그러자면 일단 스토어를 만들어야 할 것이다
    • var store = Redux.createStore(favoriteColors);
  • 모든 사항이 제대로 작동하는지 보기 위해 스토어에 컬러를 추가하거나 제거해보자
    • 그렇게 하려면 액션을 인자로 받는 dispatch 메서드를 store 객체에 사용하면 된다
    • 그리고 store.getState() 메서드로 저장된 성태값을 확인 해 볼 수 있다
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Favorite Colors!</title>
  <script src="https://unpkg.com/redux@latest/dist/redux.js"></script>
</head>

<body>
  <script>
    function addColor(value) {
      return {
        type: "ADD",
        color: value
      }
    }

    function removeColor(value) {
      return {
        type: "REMOVE",
        color: value
      }
    }

    function favoriteColors(state, action) {
      if (state === undefined) {
        state = [];
      }

      if (action.type === "ADD") {
        return state.concat(action.color);
      } else if (action.type === "REMOVE") {
        return state.filter(item => item !== action.color)
      } else {
        return state;      }
    }

    var store = Redux.createStore(favoriteColors);

    store.dispatch(addColor("blue"));
    store.dispatch(addColor("yellow"));
    store.dispatch(addColor("green"));
    store.dispatch(addColor("red"));
    store.dispatch(addColor("gray"));
    store.dispatch(addColor("orange"));
    store.dispatch(removeColor("gray"));

    console.log(store.getState());
  </script>
</body>

</html>

-5. 스토어 갱신 활성화

  • 이제 store에 저장된 상태 값이 변경될 때마다 이를 인지하고 갱신하거나 다른 작업을 수행하게 해볼것이다
  • 그렇게 하기 위해 특정 함수(리스터)를 스토어에 등록해 스토어의 변경 사항이 있을때마다 호출되게 할 수 있다
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Favorite Colors!</title>
  <script src="https://unpkg.com/redux@latest/dist/redux.js"></script>
</head>

<body>
  <script>
    function addColor(value) {
      return {
        type: "ADD",
        color: value
      }
    }

    function removeColor(value) {
      return {
        type: "REMOVE",
        color: value
      }
    }

    function favoriteColors(state, action) {
      if (state === undefined) {
        state = [];
      }

      if (action.type === "ADD") {
        return state.concat(action.color);
      } else if (action.type === "REMOVE") {
        return state.filter(item => item !== action.color)
      } else {
        return state;
      }
    }

    var store = Redux.createStore(favoriteColors);

    store.subscribe(render);

    function render() {
      console.log(store.getState());
    }

    store.dispatch(addColor("blue"));
    store.dispatch(addColor("yellow"));
    store.dispatch(addColor("green"));
    store.dispatch(addColor("red"));
    store.dispatch(addColor("gray"));
    store.dispatch(addColor("orange"));
    store.dispatch(removeColor("gray"));
  </script>
</body>

</html>


profile
아직까지는 코린이!

0개의 댓글

관련 채용 정보