import { useForm } from "react-hook-form";
import { atom, useRecoilState } from "recoil";
interface IForm {
toDo: string
}
interface IToDo {
text: string;
id: number;
category: "TO_DO" | "DOING" | "DONE"
}
const toDoState = atom<IToDo[]>({
key: "toDo",
default: [],
})
function ToDoList() {
const [toDos, setToDos] = useRecoilState(toDoState);
const {
register, handleSubmit, setValue } = useForm<IForm>();
const onSubmit = ({ toDo }: IForm) => {
setToDos(prev => [{ text: toDo, id: Date.now(), category: "TO_DO" }, ...prev]);
setValue("toDo", "")
}
console.log(toDos)
return (
<div>
<h1>To Dos</h1>
<hr />
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("toDo", {
required: "Please Write a To Do"
})} placeholder="Write a to do" />
<button>Add</button>
</form>
<ul>
{toDos.map(toDo => <li key={toDo.id}>{toDo.text}</li>)}
</ul>
</div>
)
}
export default ToDoList;
interface (IToDo)를 생성해주어야 typescript가 toDoState를 제대로 인식할 수 있음. or never[ ] ( 이해가 잘 안가..)
setToDos => 1. 직접적으로 값을 바꿀 수 있다. 2. 함수를 받아 그 return값이 새로운 state가 된다.
onSubmit에 argument인 data를 {}열어서 data.toDo가 아니라 바로 toDo 사용할 수 있게끔
이후 toDo생성하는 부분과 렌더링하는 부분을 분리
function ToDoList() {
const toDos = useRecoilValue(toDoState);
return (
<div>
<h1>To Dos</h1>
<hr />
<CreateToDo />
<ul>
{toDos.map(toDo => key={toDo.id} <ToDo {...toDo} />)}
</ul>
</div>
)
}