노마드강의의 초보자를 위한 리덕스 101을 복습하며 정리하려고 포스팅한다.
react에 redux를 사용하기 전 바닐라로 조금 더 쉽게 개념을 잡아보려고한다.
html은 간단하다
add,minus버튼과 가운데 state의 값을 나타내는 span태그로 구성하였다.
자바스크립트 코드 또한 매우 심플하다.
클릭이벤트를 이용해 각각의 버튼을 눌렀을 때
handleAdd, handleMinus함수를 실행시킨다.
각각의 함수에서는 count값을+
,-
시켜주며 updateText함수를 실행시키는데
updateText함수는 number.innerText = count 함으로써 현재 count값을 보여주는 함수이다.
이것을 이제 아주 심플한 리덕스로 교체할 것이다.
yarn add redux
import { createStore } from "redux"
Store가 하는 일은 기본적으로 data
를 넣을 수 있는 장소를 생성한다.
redux는 data를 (관리하는데) 도와주는 역할을 하기 위해 만들어졌다.
현 케이스에서는 리덕스가 -1이나 +1을 count
하는 걸 도와주기 위해 필요하다.
우리는 data
를 어딘가에 넣어줘야하고 그 데이터는 store라는 곳에
저장 되어야 한다. 자!! 그럼 store를 만들어보자.
const store = createStore();
하지만 에러가 뜰 것이다.
(Reducer가 function이어야함)
그렇다면 reducer라는 function을 만들어보자.
reducer는 함수이고 나의
data
를modify
한다.
만약 reducer가 hello라고return
하게된다면
현재application
에 있는data
가 될 것이다.
reducer라는 용어가 처음엔 어려울수 있어 rename을 해줬다.
recuer ㅡ> countModifier
countStore을 console해보면
dispatch, getState, replaceReducer, subscribe
가 있는것을
확인할 수 있고 여기서 중요한 파트인getState
를 사용해보겠다.
countModifier(reducer)는data
를 바꿔준다.
또 뭐든지return
하는 것은application
에 있는data
이다.
현 케이스처럼 만약 countModifer(reducer)가 "hello"라고return
을 하면
우리의application
의data
가 되는것이다.
state의 default값을 0으로 설정해주고 state를 console하면
default로 state는 0이 될것이다.
이것은 state를 initializing하는 것이다.
유일하게 countModififer만 state를 modify할 수 있다.
자. 그렇다면 countModifier로 하여금 ++, --를 할 수 있을까 ?
그것을 action
을 통해 가능하다.
action은 redux에서 function을 부를 때 쓰는 두번째 파라미터 혹은 argument다.
그래서 어떻게 countModifier에게 action을 보낼 수 있을까?
store를 사용하는 방법 즉 countStore.dispatch()
를 입력해서
action을 보낼 수 있다.action은 object이어야한다.
dispatch와 함께 countModifier로 메세지를 보내는 것이다.
위에서 말했듯이 countModifier가 return하는 모든 것은, data가 된다.
현 케이스에서는 action의 type이 "ADD"일때 count+1을 리턴하게 되고
console.log(countStore.getState())
를 하게 된다면
콘솔엔 state값으로 1이 찍힐 것이다.
(현재는 버튼을 누르지않아도countStore.dispatch({ type: "ADD" });
로 인해 메세지가 전달된다.)
정리하자면
data의 store를 만들고
const countStore = createStore(countModifier)
data를 modify하는 countModifier(reducer)를 만든다.
const countModifier = () => {}
message를 store에 보낼 수 있으며
message를 send 하는 방법은 dispatch를 사용하면된다.
countStore.dispatch({ type: "ADD" })
내가 전송한 message는 action에 넣으면 되고,
여기서 해야 할 일은 action을 체크해보면된다.
if(action.type === "ADD"
subscribe는 store안에 있는 변화들을 알 수 있게 해준다.
subscribe는 코드로 더 자세히 알아보자.
import { createStore } from "redux";
const add = document.getElementById('add');
const minus = document.getElementById("minus");
const number = document.querySelector('span');
number.innerText = 0;
//reducer
const countModifier = (count = 0, action) => {
console.log(count, action);
if (action.type === "ADD"){
return count + 1;
}else if(action.type === "MINUS"){
return count - 1;
}else {
return count;
}
};
//store
const countStore = createStore(countModifier);
const onChange = () => {
console.log("변화생김");
number.innerText = countStore.getState();
}
countStore.subscribe(onChange);
//익명함수 대신 핸들링해주는 함수를 만들어줬다.
const handleAdd = () => {
countStore.dispatch({ type: "ADD" });
}
const handleMinus = () => {
countStore.dispatch({ type: "MINUS" });
}
add.addEventListener('click', handleAdd);
minus.addEventListener('click', handleMinus);
store에서 subscribe을하고
countStore.subscribe();
subscribe에서 onChange함수를 실행시킨다.
countStore.subscribe(onChange);
onChange함수는 number의 innerText값을
store의 data값으로 바꿔준다.
언제? data에 변화가 생겼을때
const onChange = () => {
console.log("변화생김");
number.innerText = countStore.getState();
}
console.log를 확인해보면
버튼을 눌렀을때 변화가 생겼다고 알려준다.
마지막으로 코드를 조금 더 개선해보자.
redux 공식문서처럼
if대신 switch문으로 바꿔주었다.
reducer에게 dispatch할때 type을
string타입인 아닌 변수를 선언하여 그것을 이용해주었다.
만약 type을 MINUS가 아닌 MIN로 잘못적었을 때
const handleMinus = () => {
에러를 확인해보면
countStore.dispatch({ type: MINUS});
}
"MIN" is not defined
즉 "MIN"이 defined되지않았기 때문이라고 자바스크립트가 친절하게 알려준다.만약 string을 쓴다면 자바스크립트가 아무것도 말해주지않는다.