코로 넘어져도 헤딩만 하면 그만

Redux 기초 노마드 코더 정리(1) 본문

CODE STATES 44

Redux 기초 노마드 코더 정리(1)

꼬드리 2023. 5. 28. 23:01

리덕스 개념이 영 안 잡히길래 팀원이 추천해준 강의를 들어보았다. 그 결과, store에서 dispatch를 통해서 action객체를 보내고, 이 action이 reducer에 들어온 뒤 return 된 값이 새로 store의 data가 된다는 일련의 흐름을 이해하게 되었다. 가벼운 예제를 만들어보면서 흐름을 살펴보니(그것도 vanilla js로!) 쉽게 이해가 되는 부분이 있었다. 이건 무료로 제공되는 강의니까 리덕스가 대체 어떻게 돌아가는지 감이 안 온다면 한번쯤 들어보는 것을 추천. 

 

#0.1 ❤️ 무료 강의 ❤️ – 노마드 코더 Nomad Coders

 

All Courses – 노마드 코더 Nomad Coders

초급부터 고급까지! 니꼬쌤과 함께 풀스택으로 성장하세요!

nomadcoders.co

 

 

우선 리덕스를 설치한 뒤에는 import {createStore } from "redux";를 하는데, 리덕스에서 쓰이는 store은 기본적으로 data 를 넣을 수 있는 장소를 생성한다는 의미와 같다. 즉! 리덕스는 data 상태를 아주 탁월하게 관리해준다. 그러니 일단은 우리가 원하는 data가 store이라는 저장소에 저장이 되어야 가져다 쓸 수 있다. 그래서 일단 store를 만들게 되는데...

 

const store = createStore(reducer);

 

이러면 갑자기 에러가 뜬다. reducer을 만들어달라는 에러다. 따라서 const reducer= () => {}; 까지 해야 에러가 사라진다. reducer은 data를 수정하는 함수이다! 심플. reducer은 change data를 해준다. 

그리고 여기서 reducer가 무엇을 리턴하던 간에, 이것이 application에 있는 진짜 값 data가 될 것이다

 

+)여담이지만, createStore에 가로선이 쭉 생길 때 너무 당황할 것 없다. 요즘은 createStore보다 다른 걸 추천한다고 사용 지양해달라는 뜻인데 일단은 다들 이렇게 계속 쓰긴 하는 모양...거슬리면 없애는 방법이 몇 개 있다. 

import {createStore} from "redux";

const add = document.getElementById("add")
const minus = document.getElementById("minus")
const number = document.querySelector("span");

const countModifier = (state = 0) =>{
  //여기가 reducer이다.
  //들어온 게 undefined라면 state의 기본값을 0으로 뒀다.
  //이 reducer만 값을 수정할 수 있는 함수다. redux의 본질.
  //여기에 값을 수정하는 걸 써주면 된다. 
  return state;
}

const countStore = createStore(countModifier); //값을 저장하는 Store
console.log(countStore.getState()) //이러면 이제 data가 0이 나온다.

 

이제 이렇게 들어오는 값을 어떻게 바꿔줄 것이냐?->바로 여기서 action의 중요성이 대두된다.

 

action은 redux에서 함수를 부를 때 쓰는 두 번째 파라미터다. 이 action들이 reducer에게 이렇게 리턴해달라고 요청을 하는데, 그렇다면 이 action은 어떻게 reducer로 보내느냐.... 바로 store에서 dispatch를 사용해서 보낸다

아래와 같은 코드를 보면 좀 더 이해가 쉬울 수 있다. 여기서 action은 반드시 객체여야 하며 타입이 있어야 한다. 

const countModifier = (count = 0, action) =>{
  console.log(count, action)
  //countModifier에게 이렇게 해달라고 말하기 위한 수단이 action들
  return count;
}

const countStore = createStore(countModifier);

countStore.dispatch({type: "Hello"});
//이러면 action 객체가 dispatch를 써서 보내진다.
//action이 콘솔에서 {type: "Hello"}로 나온다.

reducer에서 action으로 들어온 타입을 확인한 뒤, 그에 걸맞는 것을 return 해주면 data가 바뀐다. 

const countModifier = (count = 0, action) =>{
  //undefined라면 state의 기본값을 0으로 뒀다.
  //얘만 값을 수정할 수 있는 함수다. 이게 redux의 본질.
  //여기에서 값을 수정하는 걸 써주면 된다. 
  //countModifier에게 이렇게 해달라고 말하기 위한 수단이 action들
  console.log(count)
    if (action.type ==="ADD") {
      return count +1;    
  }
}

const countStore = createStore(countModifier);

countStore.dispatch({type: "ADD"});
//이러면 action 객체가 dispatch를 써서 보내진다. 

console.log(countStore.getState()) //결과는 1로 바뀐다.

 

const countModifier = (count = 0, action) =>{
    if (action.type ==="ADD") {
      return count +1;    
  } else if(action.type ==="MINUS") {
    return count -1;
  }
  return count;
}

const countStore = createStore(countModifier);

countStore.dispatch({type: "ADD"}); //1
countStore.dispatch({type: "ADD"}); //2
countStore.dispatch({type: "ADD"}); //3
countStore.dispatch({type: "MINUS"}); //2
//이러면 action 객체가 dispatch를 써서 보내진다.

이런 식으로 dispatch를 사용해서 action을 보내는 만큼 값이 바뀌게 된다. 

 

const countStore = createStore(countModifier);

const onChange = () => {
  console.log("there was a change on the store")
  number.innerText = countStore.getState()
  //subscribe는 change가 생길 때 감지한다.
}
countStore.subscribe(onChange);

add.addEventListener("click", ()=> countStore.dispatch({type: "ADD"}))
minus.addEventListener("click", ()=>countStore.dispatch({type: "MINUS"}))

 

최종적으로 click이 일어났을 때 수가 바뀔 수 있도록 개선한 코드는 위와 같다. click이벤트가 발생할 때마다 디스패치를 보내주고, 바뀔 때마다 subscribe로 감지해서 바꾸어준다. 

 

 

+) 코드 개선하기

그런데 이렇게 if else 를 반복하지 않고도 switch를 써서 더 깔끔하게 작성할 수 있다.

실제로 리덕스에서 상태액션을 받아올 때 switch를 자주 쓴다. 

const countModifier = (count = 0, action) =>{
  switch(action.type){
      case "ADD": 
    return count +1 
      case "MINIIS":
      return count -1
    default: 
      return state
  }
}

 

또한 액션들을 이런 식으로 변수에 넣어 지정 뒤 관리해주는 것이 오타를 방지하는 데에 아주 효과적이다. 

const ADD = "ADD";
const MINUS = "MINUS";

const countModifier = (count = 0, action) =>{
  switch(action.type){
      case ADD: 
    return count +1 
      case MINUS:
      return count -1
    default: 
      return state
  }
}

 

 

 

Comments