노마드코더 리덕스 - Vanilla(2)

이동주·2022년 5월 25일
0

리덕스를 사용한 바닐라 To-Do-List

1. Vanilla ToDo

기본세팅

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 reducer = (state = [], action) => {
  console.log(action);
    case ADD_TODO:
      return [];
    case DELETE_TODO:
      return [];
    default:
      return state;
   }
};

const store = createStore(reducer);

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

(1) state를 절대 mutate 하면 안됨!

store을 수정할 수 있는 법action을 보내는 방법뿐
=> mutating state를 하는 대신에 new state objects를 리턴
=> state는 read-only

What is "mutation"?

const friends = ["dongduu"];
friends.push("dal")

잘못된 리듀서 사용 예(mutation)

const reducer = (state = [], action) => {
    case ADD_TODO:
      state.push(action.text);
    ...
   }
};

올바른 리듀서 사용 예(new state objects)

const reducer = (state = [], action) => {
    case ADD_TODO:
      return [{ text: action.text, id: Date.now() }, ...state]
    ...
   }
};

3. Delete To Do

(1) 함수로 나누기

dispatch는 따로 함수로 만들어서 나누는 것이 보기 좋음

...

const addToDo = text =>  {
	store.dispatch({ type: ADD_TODO, text: toDo });
}

const onSubmit = e => {
  e.preventDefault();
  const toDo = input.value;
  input.value = "";
  addToDo(toDo);
};

...

(2) paint to do

기능을 추가하기 전에 필요한 UI를 먼저 구성해보쟝

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", deleteToDo);
    
    li.id = toDo.id;
    li.innerText = toDo.text;
    li.appendChild(btn);
    
    ul.appendChild(li);
  });
};

(3) delete to do

DEL 버튼이 눌리면 toDo의 id를 선택해서 해당 id의 toDo를 삭제할 수 있게 함

const deleteToDo = e => {
	const id = e.target.parentNode.id;
    store.dispatch({ type: DELETE_TODO });
}

(4) action 분리

코드 최적화를 위해 action 만을 return 하는 함수를 만들어서 action을 분리함

const addToDo = text => {
  return {
    type: ADD_TODO,
    text
  };
};

const deleteToDo = id => {
  return {
    type: DELETE_TODO,
    id
  };
};

const dispatchAddToDo = text => {
  store.dispatch(addToDo(text));
};

const dispatchDeleteToDo = e => {
  const id = e.target.parentNode.id;
  store.dispatch(deleteToDo(id));
};

4. Delete To Do part Two

(1) 삭제는 어떻게 하는가?

직접 배열에 변화를 주는 slice 대신 새로운 array를 만드는 filter를 사용!

const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

const result = words.filter(word => word.length > 6);

console.log(result);
// expected output: Array ["exuberant", "destruction", "present"]

(2) DELETE_TODO

dispatch로 받은 id와 같지 않은 toDo들만 남겨서 DELETE_TODO를 완성해보쟈

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;
 }

5. Conclusions

리덕스 사용 시 중요한 점

  • function을 사용해서 코드를 잘게잘게 쪼개라
  • state를 mutate 하지 않고 새로운 배열로 return 해라
profile
안녕하세요 이동주입니다

0개의 댓글