Requêter la base
Client
Avant de pouvoir requêter la base il faut créer un client côté serveur qui ouvrira une connexion entre le serveur et la DB.
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient()
export default prismaLister les éléments
TodoItem
Commencons par créer le composant qui correspond à un item de Todo.
import { Todo } from "@prisma/client"
const TodoItem = ({todo}: {todo: Todo}) => {
return (
<li>{todo.content}</li>
)
}
export default TodoItemTodoList.tsx
Puis Le composant qui va lister les todos:
import { Todo } from "@prisma/client"
import TodoItem from "./TodoItem"
const TodoList = ({todos}: {todos: Todo[]}) => {
return (
<ul>
{todos.map((todo) => <TodoItem key={todo.id} todo={todo} />)}
</ul>
)
}
export default TodoListpage.tsx
Enfin on peut l’importer dans une route app/todo-app/page.tsx et requêter la base dans une fonction asynchrone car il s’agit là d’un Server component:
import db from '../../frameworks/db'
import TodoList from '@/components/TodoList'
const getTodos = async () => {
const todos = await db.todo.findMany({})
return todos
}
const TodoApp = async () => {
const todos = await getTodos()
return (
<div>
<h2>TodoList</h2>
<TodoList todos={todos} />
</div>
)
}
export default TodoAppNewTodoForm.tsx
Pour soumettre une nouvelle todo nous allons créer un composant qui intègrera un formulaire.
Nous utiliserons une server action pour effectuer la requête d’écriture en base.
On peut comparer cette fonction à une route d’API en POST qui va recevoir et traiter de la donnéee.
L’avantage ici c’est qu’on est toujours dans le contexte de Next.js donc on va pouvoir informer le client qu’on peut invalider une route par exemple.
Avant de créer le composant créons l’action qui permet de créer une Todo en base.
'use server'
import { revalidatePath } from 'next/cache';
import db from '../frameworks/db'
export const createTodo = async (formData: FormData) => {
const content = formData.get('content');
if (typeof content !== 'string') {
throw new Error('invalid params provided')
}
await db.todo.create({
data: {
content
}
})
revalidatePath('/todo-app')
}Notez la première ligne qui indique bien que les fonctions présentes dans ce fichier seront executées côté serveur.
enfin intégrons à notre composant le formulaire qui fera appel à la server action:
import { createTodo } from "@/actions/todos"
const NewTodoForm = () => {
return (
<form action={createTodo}>
<input type="text" name="content" className="border border-black/25"/>
</form>
)
}
export default NewTodoFormlayout.tsx
On peut alors ajouter un layout à ce nouveau dossier app/todo-app au même niveau que le fichier page.tsx afin d’intégrer un composant de formulaire:
import NewTodoForm from "@/components/NewTodoForm";
type Props = Readonly<{
children: React.ReactNode;
}>
const TodoAppLayout = ({children}: Props) => {
return (
<>
<div>TodoApp</div>
<NewTodoForm />
<div>{children}</div>
</>
)
}
export default TodoAppLayout