nextjs is a nodejs library that is a framework for building modern web apps from backend and frontend. Here I will share my experience of learning nextjs by coding a todo list demo project. Here is my project repository
create a nextjs project
We may create a floder for our project:
1 2 3
mkdir nextjs-demo-todo-list cd todoList-demo-by-nextjs npx create-next-app@latest .
install dependencies
For our simple demo project, we need to install prisma, that is a open-source ORM for nodejs.
1
npm install prisma
and we just use prisma to generate a sqlite database file:
1
npx prisma init --datasouce-provider sqlite
create the ORM model and migrate the db schema
in prisma/schema.prisma file, we may updated as below:
1 2 3 4 5 6 7
model Todo { id String @id @default(uuid()) title String complete Boolean createAt DateTime @default(now()) updateAt DateTime @updatedAt }
run the migrate command:
1
npx prisma migrate dev --name init
we may see the prisma/migrations floder, and see the sql file.
// "use server" field might be the nextjs way to handle the server side logic. const toggleItem = async (id: string, complete: boolean) => { "use server"; await prisma.todo.update({ where: { id, }, data: { complete, }, }); };
const deleteItem = async (id: string) => { "use server"; await prisma.todo.delete({ where: { id, }, }); // here refresh the page again, we may see that the item deleted. redirect("/"); };
const Home = async () => { // fetching the data from the db: const todos = await getTodos();
"use client"; // TodoItem function is the server side function, so we must mark "use client" field for this component type TodoItemProps = { id: string, title: string, complete: boolean, toggleItem: (id: string, complete: boolean) =>void, deleteItem: (id: string) =>void, };
const TodoItem = ({ id, title, complete, toggleItem, deleteItem, }: TodoItemProps) => { return ( <li className="flex gap-1 items-center"> {/* here using the call back function toggleItem to pass the id and value: */} <input id={id} type="checkbox" className="cursor-pointer peer" defaultChecked={complete} onChange={(e) => toggleItem(id, e.target.checked)} /> <label htmlFor={id} className="peer-checked:line-through"> {title} </label> <div className="cursor-pointer rounded-full" onClick={() => deleteItem(id)} > ❌ </div> </li> ); };