거북이개발자

[Redux] Pure Redux 이용한 To-Do List 만들기 본문

Redux

[Redux] Pure Redux 이용한 To-Do List 만들기

류정식 2021. 2. 22. 01:30

0. 구현 사항

-vanilla js와 pure redux를 이용한 To-Do List를 구현한다.

 

 

 

1. 전체 코드

 

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)=>{

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

const store=createStore(reducer);

store.subscribe(()=>console.log(store.getState()));

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

store.subscribe(paintToDos);

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

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

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

form.addEventListener("submit", onSubmit);

 

 

2. Create

 

(1). store 생성

 

const store=createStore(reducer);

 

 

(2). reducer

 

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

 

- state를 mutate 하면 안 된다. 그렇기 때문에 spread를 이용하여 새로운 객체를 return 해준다.

 

(3). dispatch

 

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


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

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

-onSubmit 함수를 이용해 입력이 되면 입력된 값을 dispatch 해준다.

 

 

 

 

3. paint toDos

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

 

-getState를 통해서 입력된 text가 있는 state를 toDos에 저장한다.

-forEach함수를 통해서 한 개의 객체만 다룬다.

-li를 만들 뒤 ul에 삽입해주면 된다.

 

 

 

 

4. Delete

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

-button을 만든 뒤 이벤트 리스너를 걸어준다.

 

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


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

-event.target.partNode.id를 통해 들어온 id를 dispatch 해준다.

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

return state로 state.filter을 사용해주는데 slice를 안 쓰는 이유는 state를 mutate하지 않기 위해서다.

Comments