📜 지금 리액트와 리덕스를 공부하고 있지만, 리덕스를 정확하게 이해하기 위해서 바닐라자바스크립트에 리덕스를 적용해서 리덕스를 왜 사용하는지에 대해 정확히 공부하는 중이다!
그래서 리덕스가 왜 필요하고, 어떻게 사용해야되는지 이전 글과 본 글에서 정리를 할 것이다.
Vanilla JavaScript와 Redux를 사용해서 ToDoList를 만들어보았다.
- 먼저 state관리를 하기 위해서 createStore를 받아오고 거기에 리듀서를 연결해 줄 것이다.
- 리듀서에서는 action에 따라 동작할 작업을 정의해 줄 것이다.
- 액션별로 어떤 것을 리턴할 지 따로 함수로 정의해 줄 것이다.
- state를 가지고 각각의 태그들을 만들고 이벤트를 처리해 볼 것이다.
state를 관리하기 위해서 리덕스의 createStore를 가져온다.
import { createStore } from 'redux';
DOM 요소들을 가져온다.
const form = document.querySelector('form'); const input = document.querySelector('input'); const ul = document.querySelector('ul');
action의 타입을 변수로 지정한다.
const ADD_TODO = "ADD_TODO"; const DELETE_TODO = "DELETE_TODO";
각 action별로 할 동작을 정의하여 리턴한다.
const addToDo = (text) => { return { type: ADD_TODO, text } } const deleteToDo = (id) => { return { type: DELETE_TODO, id } }
dispatch를 통해 action을 전달받으면 각각의 state, action을 갖고 처리할 리듀서를 구현한다.
const reducer = (state = [], action) => { switch (action.type) { case ADD_TODO: return [{ text: action.text, id: Date.now() }, ...state]; case DELETE_TODO: return state.filter((toDo) => toDo.id !== action.id); default: return state; } }
store를 사용하기 위해 createSotre(reducer)를 만든다.
const store = createStore(reducer);
dispatch를 통해 reducer로 action을 보낸다.
const dispatchAddToDo = (text) => { store.dispatch(addToDo(text)); } const dispatchDeleteToDo = (e) => { const id = parseInt(e.target.parentNode.id); store.dispatch(deleteToDo(id)); }
state를 가지고 화면에 리스트를 뿌리는 함수를 정의
const paintToDos = () => { const toDos = store.getState(); ul.innerHTML = ''; toDos.forEach((toDo) => { const li = document.createElement('li'); li.id = toDo.id; li.innerText = toDo.text; const delBtn = document.createElement('button'); delBtn.innerText = 'DEL'; delBtn.addEventListener('click', dispatchDeleteToDo); li.appendChild(delBtn); ul.appendChild(li); }); }
subscribe가 일어날 때 마다 위의 리스트 뿌리는 함수를 호출한다.
store.subscribe(paintToDos); const onSubmit = (e) => { e.preventDefault(); const toDo = input.value; input.value = ''; dispatchAddToDo(toDo); }
eventhandler
form.addEventListener('submit', onSubmit);