안녕하세요 건브로입니다.
오늘은 Redux에 대해서 정리를 해보려고 합니다.
1. Redux란 무엇인가?
Redux란 상태 관리를 쉽게 해주는 자바스크립트 기반 기술이다.
아마 react를 하면서 redux를 같이 배우는 사람들이 많은 걸로 알고 있다.
나도 이번에 react 공부하다가 redux를 알게 되었고 공부하게 되었다.
2. Redux 코드들 분석하기
Redux에는 여러 가지 함수들이 있다.
1) createStore()
createStore()는 데이터를 넣을 수 있는 장소를 생성해주는 함수이다.
하지만 createStore의 인수로는 reducer 인수가 들어가야 한다.
2) reducer()
reducer()는 data를 수정하는 함수이다.
return 값으로는 state data를 전달할 수 있다.
state는 참고로 바뀌는 데이터를 말한다.
reducer()는 형식적인 이름이며 입맛대로 이름을 바꿀 수 있다.
const reducer = (state = 0, action) => {
switch(action.type){
case: "ADD":
return state + 1;
case: "MINUS":
return state - 1;
default:
return state;
}
}
reducer()에는 두 가지의 인수가 있다.
첫 번째 인수로는 바뀌는 데이터(state)를 넣을 수 있다.
두 번째 인수로는 action이라는 객체이다.
action에는 type이라는 key가 존재한다.
그래서 주로 위의 코드처럼 type에 따라서 state 값을 수정할 수 있게 한다.
하지만 state 값을 수정하더라도 객체일 때는 조심해야 한다.
위의 state가 객체(배열도 객체임)라고 해보자.
아래와 같이 새로운 객체를 만들어서 기존의 데이터와 새로운 데이터를 함께 넣어야 한다.
const reducer = (state=[], action) => {
switch(action.type){
case: "ADD":
const newArray = {text: action.text, id: Date.now()};
return [newArray, ...state];
default:
return state;
}
}
만약 이렇게 하지 않고 기존의 객체에 변화를 주면 어떻게 될까?
한 번 해보자.
밑에 사진은 맨 아래의 todolist 코드에서 해본 결과이며,
위의 예시 코드와는 다른 코드지만 결과는 다를 바 없다.
이렇게 기존에 연결되던 코드들이 오류가 생긴다.
아래의 Redux 문서에서는
이전 상태를 변경하는 대신 새로운 상태 객체를 생성해서 반환해야 한다는 사실을 기억해야 합니다.
라고 나와 있다. 그러니 새로운 객체를 만들어서 반환하자!
3가지 원칙 | Redux
소개 > 3가지 원칙: Redux 사용의 3가지 중요 원칙
ko.redux.js.org
3) getState()
getState()는 createStore()의 하위 함수이며,
현재의 state값을 알려준다.
4) subscribe(listener)
subscribe()도 마찬가지로 createStore()의 하위 함수이며,
감시하는 역할을 한다.
감시라는 것은 createStore가 reducer를 부를 때마다 수행하는 거라고 보면 된다.
마치 React의 useEffect와 조금은 비슷해 보인다.
대신 createDidUpdate기능만 있다고 생각하면 된다.
subscribe()에 인수로 함수를 넣어야 한다.
5) dispatch(action)
dispatch()도 마찬가지로 createStore의 하위 함수이다.
그리고 action의 값을 바꿔주면서 reducer가 조건적으로 state를 바꾸게 한다.
dispatch()를 사용하면 reducer를 한 번 더 부르게 된다.
결국에는 subscribe는 dispatch가 실행될 때 수행한다.
6) replaceReducer(nextReducer)
현재 저장소에서 상태를 계산하기 위해 사용 중인 리듀서를 교체한다. 이것은 고급 API로 코드 분할이나 동적으로 리듀서를 불러오고 싶을 때 사용할 수 있다. Redux에서 핫 리로딩을 구현하기 위해서도 사용할 수 있다.
Store | Redux
Store
ko.redux.js.org
3. counter 코드(연습 코드1)
import { createStore } from "redux";
const add = document.getElementById("Add");
const minus = document.getElementById("Minus");
const number = document.querySelector("span");
number.innerText = 0;
const ADD = "ADD";
const MINUS = "MINUS"
const countModifier = (state = 0, action) => {
// if (action.type === "ADD") {
// return state + 1;
// } else if (action.type === "MINUS") {
// return state - 1;
// } else {
// return state;
// }
//주로 switch문을 쓴다고 한다.
switch (action.type) {
case ADD:
return state + 1;
case MINUS:
return state - 1;
default:
return state;
}
};
const countStore = createStore(countModifier);
// console.log(countStore.getState());
const onChange = () => {
number.innerText = countStore.getState();
}
countStore.subscribe(onChange);
const addFun = () => {
countStore.dispatch({ type: ADD });
console.log(countStore.getState());
};
const minusFun = () => {
countStore.dispatch({ type: MINUS });
console.log(countStore.getState());
};
add.addEventListener("click", addFun);
minus.addEventListener("click", minusFun);
4. todolist 코드(연습 코드2)
<body>
<h1>To Dos</h1>
<form>
<input type="text" placeholder="Write to do" />
<button>Add</button>
</form>
<ul></ul>
</body>
1) 바닐라 자바스크립트
이 코드에 단점이 있다. 바로 데이터를 저장할 수 없다는 거다.
그냥 html에만 변화를 주기 때문이다.
const form = document.querySelector("form");
const input = document.querySelector("input");
const ul = document.querySelector("ul");
const createToDo = (toDo) => {
const li = document.createElement("li");
li.innerText = toDo;
ul.appendChild(li);
}
const onSubmit = e =>{
e.preventDefault();
const toDo = input.value;
input.value="";
createToDo(toDo);
}
2) 바닐라 자바스크립트 + Redux
자바스크립트와 Redux를 같이 사용한다면 데이터를 보다 쉽게
때에 따르게 저장도 가능하며 삭제도 가능해진다.
import { createStore } from "redux";
const form = document.querySelector("form");
const input = document.querySelector("input");
const ul = document.querySelector("ul");
const ADD_TODO = "ADD_TODO";
const DELETE_TODO = "DELETE_TODO";
const addToDo = (text) => {
return {
type: ADD_TODO,
text,
};
};
const deleteToDo = (id) => {
return {
type: DELETE_TODO,
id,
};
};
const reducer = (state = [], action) => {
console.log(action.text);
switch (action.type) {
case ADD_TODO:
const newToDoObj = { text: action.text, id: Date.now() };
return [newToDoObj, ...state];
case DELETE_TODO:
const cleaned = state.filter((toDo) => toDo.id !== action.id);
return cleaned;
default:
return state;
}
};
const store = createStore(reducer);
store.subscribe(() => console.log(store.getState()));
const dispatchAddToDo = (text) => {
store.dispatch(addToDo(text));
};
const dispatchDeleteToDo = (e) => {
const id = parseInt(e.target.parentNode.id);
store.dispatch(deleteToDo(id));
};
const paintToDos = () => {
const toDos = store.getState();
ul.innerHTML = "";
toDos.forEach((toDo) => {
const li = document.createElement("li");
const btn = document.createElement("button");
btn.innerText = "DEL";
btn.addEventListener("click", dispatchDeleteToDo);
li.id = toDo.id;
li.innerText = toDo.text;
li.appendChild(btn);
ul.appendChild(li);
});
};
store.subscribe(paintToDos);
const onSubmit = (e) => {
e.preventDefault();
const toDo = input.value;
input.value = "";
dispatchAddToDo(toDo);
};
form.addEventListener("submit", onSubmit);
출처: nomadcoders.co/redux-for-beginners/lobby
Watch Now - 노마드 코더 Nomad Coders
nomadcoders.co
여기까지!
'관심있는 언어들 > Javascript' 카테고리의 다른 글
[Javascript]Array 내장 함수 (0) | 2021.07.07 |
---|---|
[Javascript] 자주 사용하는 ES6 문법 (0) | 2021.07.05 |
[Javascript] HTTP통신에 대하여 (0) | 2021.03.11 |
callback, Promise, async & await (0) | 2021.01.02 |