Add To Do
- 이번에는
ToDoList.tsx
컴포넌트 파일에 모든 걸 넣어놓지만 나중에는 모든걸 다 분리 시킬 계획입니다. (아직 배우지 않은 Recoil
의 기능을 배우기 위해서)
useRecoilState(초기값)
사용, useState
와 유사합니다.
// ToDoList.tsx
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 [x, setX] = useState(); 와 거의 비슷
const {
register,
handleSubmit,
formState: { errors },
setError,
setValue,
} = useForm<IForm>();
const onValid = ({ toDo }: IForm) => {
if (toDo.includes("게임")) {
setError(
"toDo",
{ message: "게임을 하면 안됩니다." },
{ shouldFocus: true }
);
}
setToDos((oldToDos) => [
{ text: toDo, id: Date.now(), category: "TO_DO" },
...oldToDos,
]);
setValue("toDo", "");
};
return (
<div>
<h1>To Dos</h1>
<hr />
<form onSubmit={handleSubmit(onValid)}>
<input
{...register("toDo", {
minLength: {
value: 10,
message: "too short",
},
pattern: {
value: /^[ㄱ-ㅎㅏ-ㅣ가-힣0-9]/,
message: "only korean & numbers",
},
validate: {
noYoutube: (value) =>
value.includes("유튜브") ? "유튜브를 보면 안됩니다." : true,
},
})}
placeholder="Write a to do"
/>
<button>Add</button>
<span>{errors?.toDo?.message}</span>
</form>
<ul>
{toDos.map((toDo) => (
<li key={toDo.id}>{toDo.text}</li>
))}
</ul>
</div>
);
}
export default ToDoList;