Frontend/React

(20) React -To Do App(Components) (2)

creativeDeveloper! 2023. 1. 26. 23:12
728x90
// CreateToDo.tsx 

import { useForm } from "react-hook-form";
import { useRecoilValue, useSetRecoilState } from "recoil";
import { categoryState, toDoState } from "../atoms";


interface IForm {
    toDo: string;
}  

function CreateToDo(){
    // component를 가져올때 다시 사용하는것이아니라
    // 수정할수 있도록만 해주면됨.
    const setToDos = useSetRecoilState(toDoState);
    const category = useRecoilValue(categoryState);
    const {register,handleSubmit,setValue} = useForm<IForm>();
    const handleValid = ({toDo}:IForm) =>{
        // console.log("add to do",data.toDo);
        setToDos((prev) =>[
            {
            text: toDo,
            id:Date.now(),
            category
        } ,
        ...prev,
    ]);
        //  prev을 받아서 prev배열 자체가 아닌
        //  prev안의 요소들을 return 할것이기때문에 '...'를 붙여준다.
        setValue("toDo","");
        // console.log(toDos);
    };
    return(
        <form onSubmit=
        {handleSubmit(handleValid)}>
           <input
           {...register("toDo",{
               required: "please write a To Do",
           })}
           placeholder="Write a to do"
           />
       
           <button>Add</button>

      </form>
    );
}
export default CreateToDo;
ToDo.tsx 

import React from "react";
import { useSetRecoilState } from "recoil";
import { Categories, IToDo,toDoState } from "../atoms";

function ToDo({text,category,id}:IToDo){
    const setToDos = useSetRecoilState(toDoState);
    const deleteToDos = () => {
        setToDos((oldToDos) => {
            const targetIndex = oldToDos.findIndex((toDo) => toDo.id === id);
            return[
                ...oldToDos.slice(0,targetIndex),
                ...oldToDos.slice(targetIndex+1),
            ];
        });
    };

    const onClick = (event:React.MouseEvent<HTMLButtonElement>) =>
    {
         
        
        const {
            currentTarget:{name},
        }
        = event;
        setToDos((oldToDos) => {
            const targetIndex = oldToDos.findIndex((toDo) => toDo.id === id);
            // console.log(targetIndex);
            // const oldToDos = oldToDos[targetIndex];
            const newToDos = {text, id, category: name as any};
            // as any라고 적음으로써 타입스크립트에게 체크하지 말라함
            return [...oldToDos.slice(0,targetIndex),
            newToDos,
            ...oldToDos.slice(targetIndex+1)
        ];
        });
    };
        return (  
        <li>
        <span>{text}</span> 

        {category !== Categories.DOING && (
        <button name={Categories.DOING+""} onClick={onClick}>
          Doing
        </button>
      )}
            
        {category !== Categories.TO_DO && (
        <button name={Categories.TO_DO+""}  onClick={onClick}>
            To Do
        </button>
        )}

        {category !== Categories.DONE &&(
             <button name={Categories.DONE+""} onClick={onClick}>
                Done
             </button>
             )}
             
             <button onClick={deleteToDos}>
                Delete
             </button>
        </li>
    );
}

export default ToDo;
// ToDoList.tsx

import React from "react";
import { useRecoilState, useRecoilValue} from "recoil";
import { Categories, categoryState, toDoSelector } from "../atoms";
import CreateToDo from "./CreateToDo";
import ToDo from "./ToDo";

function ToDoList(){
   
    const toDos  = useRecoilValue(toDoSelector);
    // useRecoilValue는 atom과 selector의 값만 반환한다.
    const [category, setCategory] = useRecoilState(categoryState);
    // useRecoilState는 값과 더불어 modifier함수도 제공
    const onInput =(event:React.FormEvent<HTMLSelectElement>) => 
    { setCategory(event.currentTarget.value as any)};
    console.log(category);

    return(
        <div>
            <h1>To Dos</h1>
            <hr/>
            
            <select value={category} onInput={onInput}>
                <option value={Categories.TO_DO}>To Do</option>
                <option value={Categories.DOING}>Doing</option>
                <option value={Categories.DONE}>Done</option>
            </select>
            
                <CreateToDo/>        
                {toDos?.map((toDo) => (
                    <ToDo key={toDo.id} {...toDo}/>
                ))}    
                </div>
    );
}


export default ToDoList;
728x90

'Frontend > React' 카테고리의 다른 글

ToDoList에 현재시간 만들기  (0) 2023.01.31
ToDoList에 localstorage 만들기  (0) 2023.01.31
(19) React -To Do App (1)  (0) 2023.01.26
(18) React - selector modify  (0) 2023.01.25
(17) React- React hook form  (0) 2023.01.23