1. Vanilla ToDo
* 기능: 내용을 작성하고 Add 버튼을 누르면 ul 태그가 아래에 추가되는 투두리스트
index.html
<h1>To Dos</h1>
<form>
<input type="text" placeholder="Write to do" />
<button>Add</button>
</form>
<ul></ul>
index.js
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";
// Reducer: modify state
const reducer = (state = [], action) => {
// Action
console.log(action);
switch (action.type) {
case ADD_TODO:
return [];
case DELETE_TODO:
return [];
default:
return state;
}
};
// Store: data area
const store = createStore(reducer);
// sending message
const onSubmit = e => {
e.preventDefault();
const toDo = input.value;
input.value = "";
store.dispatch({ type: ADD_TODO, text: toDo });
};
form.addEventListener("submit", onSubmit);
2. State Mutation
- state is immutable (변경 불가)
- 기존 배열에 직접 값을 추가할 수 없음
// Reducer: modify state
const reducer = (state = [], action) => {
// Action
switch (action.type) {
case ADD_TODO:
return return [{ text: action.text, id: Date.now() }, ...state]; // 기존 배열에 직접 값을 추가하지 말기! state is immutable(변경 불가)
case DELETE_TODO:
return [];
default:
return state;
}
}
3. Delete ToDo
- store.dispatch({ type: ADD_TODO, text })을 수행하는 함수 addToDo 생성
- 삭제 기능을 구현하기 위해 투두를 paint하는 함수 paintToDos 생성
- 투두 리스트를 삭제하는 함수 deleteDoDo 생성
- state를 mutate하지 않도록 array.filter() 함수 사용하여 새로운 배열 생성
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,
};
};
// Reducer: modify state
const reducer = (state = [], action) => {
// Action
switch (action.type) {
case ADD_TODO:
return [{ text: action.text, id: Date.now() }, ...state]; // 기존 배열에 직접 값을 추가하지 말기! state is immutable(변경 불가)
case DELETE_TODO:
return state.filter((toDo) => toDo.id !== action.id); // 삭제하고자 하는 id를 갖고 있지 않은 배열만 필터링
default:
return state;
}
};
// Store: data area
const store = createStore(reducer);
const dispatchAddToDo = (text) => {
store.dispatch(addToDo(text));
};
const dispatchDeleteToDo = (e) => {
const id = parseInt(e.target.parentNode.id); // 삭제할 부모 노드의 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;
ul.appendChild(li);
li.appendChild(btn);
});
};
store.subscribe(() => console.log(store.getState()));
store.subscribe(paintToDos);
// sending message
const onSubmit = (e) => {
e.preventDefault();
const toDo = input.value;
input.value = "";
dispatchAddToDo(toDo);
};
form.addEventListener("submit", onSubmit);
4. Conclusions
- dispatchAddToDo, dispatchDeleteToDo: action을 dispatch하기 위한 용도의 함수
- addToDo, deleteToDo: reducer 함수에 전달되는 action 객체를 리턴
- state는 변경할 수 없음(immutable): 여기서는 toDos 배열을 직접 수정하지 않고 새로운 배열 생성
- 배열의 filter 함수: test 조건을 통과한 요소만 남겨서 새로운 배열 생성
- store.subscribe(paintToDos): ToDo의 변화에 맞추어 배열을 repainting
'Group Study (2022-2023) > React.js' 카테고리의 다른 글
[React] 4주차 스터디 - (심화) React Redux (0) | 2022.11.06 |
---|---|
[React] 4주차 스터디 - Handling Events & react-router-dom (0) | 2022.11.06 |
[React] 3주차 스터디 - (입문) React의 Hooks (0) | 2022.10.28 |
[React] 2주차 스터디 - (심화) PURE REDUX: COUNTER (0) | 2022.10.09 |
[React] 2주차 스터디 - (입문) React의 핵심 개념 익히기 (컴포넌트, Props, State, Lifecycle) (0) | 2022.10.09 |