Réagir – Actions du serveur
Réagissez aux actions du formulaire.
React a introduit de nouvelles actions de formulaire et des hooks associés pour améliorer les formulaires natifs et rationaliser la communication client-serveur. Ces fonctionnalités permettent aux développeurs de gérer plus efficacement les soumissions de formulaires, améliorant ainsi à la fois l'expérience utilisateur et la maintenabilité du code. Pour une exploration approfondie des actions de formulaire React, vous pouvez vous référer à mon article détaillé sur mon article sur les actions de formulaire React.
Actions du serveur
Avec React 18, la fonctionnalité Composants Serveur a été introduite. Les composants du serveur ne sont pas rendus côté serveur (SSR), les composants du serveur sont exécutés exclusivement sur le serveur pendant l'exécution et la construction. Ces composants peuvent accéder aux ressources côté serveur, telles que les bases de données et le système de fichiers, mais ils ne sont pas capables d'effectuer des actions côté client comme les écouteurs d'événements ou les hooks.
Conditions préalables
Pour démontrer les capacités des composants serveur et des actions serveur, nous utiliserons Next.js et Prisma.
Next.js est un framework React permettant de créer des applications Web full-stack. Vous utilisez les composants React pour créer des interfaces utilisateur et Next.js pour des fonctionnalités et des optimisations supplémentaires. Sous le capot, Next.js résume et configure automatiquement les outils nécessaires à React, comme le regroupement, la compilation, etc. Cela vous permet de vous concentrer sur la création de votre application au lieu de passer du temps sur la configuration. en savoir plus
Prisma est un ORM qui simplifie l'accès et les opérations aux bases de données, vous permettant d'interroger et de manipuler des données sans écrire de SQL. En savoir plus
Configuration initiale
Commencez par créer une nouvelle application Next.js :
Yarn Create Next-App Server-Exemple
Votre structure de dossiers initiale ressemblera à ceci :
Mettez à niveau vers la version Canary pour accéder aux fonctionnalités de React 19, y compris les actions du serveur :
yarn add next@rc react@rc react-dom@rc
installer Prisma
yarn add prisma
Configuration Prisma
Créez un fichier de schéma Prisma sur src/lib/prisma/schema.prisma :
generator client { provider = "prisma-client-js" } datasource db { provider = "sqlite" url = "file:./dev.db" } model User { id Int @id @default(autoincrement()) email String @unique name String? age Int }
À des fins de démonstration, nous utilisons SQLite. Pour la production, vous devez utiliser une base de données plus robuste.
Ensuite, ajoutez un fichier client Prisma à src/lib/prisma/prisma.ts
// ts-ignore 7017 is used to ignore the error that the global object is not // defined in the global scope. This is because the global object is only // defined in the global scope in Node.js and not in the browser. import { PrismaClient } from '@prisma/client' // PrismaClient is attached to the `global` object in development to prevent // exhausting your database connection limit. // // Learn more: // https://pris.ly/d/help/next-js-best-practices const globalForPrisma = global as unknown as { prisma: PrismaClient } export const prisma = globalForPrisma.prisma || new PrismaClient() if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma export default prisma
Configurez Prisma dans package.json :
{ //other settings "prisma": { "schema": "src/lib/prisma/schema.prisma", "seed": "ts-node src/lib/prisma/seed.ts" } }
Et mettez à jour les paramètres TypeScript dans tsconfig.json :
{ //Other settings here... "ts-node": { // these options are overrides used only by ts-node // same as the --compilerOptions flag and the // TS_NODE_COMPILER_OPTIONS environment variable "compilerOptions": { "module": "commonjs" } } }
Installez ts-node globalement :
yarn global add ts-node
Amorçage des données initiales
Ajoutez un fichier de départ dans src/lib/prisma/seed.ts pour remplir les données initiales :
import { PrismaClient } from "@prisma/client"; const prisma = new PrismaClient(); async function main() { await prisma.user.create({ email: "anto@prisma.io", name: "Anto", age: 35, }); await prisma.user.create({ email: "vinish@prisma.io", name: "Vinish", age: 32, }); } main() .then(async () => { await prisma.$disconnect(); }) .catch(async (e) => { console.error(e); await prisma.$disconnect(); process.exit(1); });
Installer le client Prisma
yarn add @prisma/client
Exécutez la commande de migration :
yarn prisma migrate dev --name init
Si les données de départ ne sont pas reflétées, ajoutez-les manuellement :
yarn prisma db seed
Super ! Puisque les installations sont prêtes, vous pouvez créer un fichier d'actions qui effectue des opérations de base de données.
Création d'actions de serveur
Les actions serveur sont une fonctionnalité puissante qui permet une intercommunication client-serveur transparente. Créons un fichier pour les opérations de base de données sur src/actions/user.ts :
"use server"; import prisma from '@/lib/prisma/prisma' import { revalidatePath } from "next/cache"; // export type for user export type User = { id: number; name: string | null; email: string; age: number; }; export async function createUser(user: any) { const resp = await prisma.user.create({ data: user }); console.log("server Response"); revalidatePath("/"); return resp; } export async function getUsers() { return await prisma.user.findMany(); } export async function deleteUser(id: number) { await prisma.user.delete({ where: { id: id, }, }); revalidatePath("/"); }
Implémentation des composants du serveur
Créons un composant serveur React pour lire et restituer les données de la base de données. Créez src/app/serverexample/page.tsx :
import UserList from "./Users"; import "./App.css" export default async function ServerPage() { return ( <div classname="app"> <header classname="App-header"> <userlist></userlist> </header> </div> ); }
Ajoutez du style dans src/app/serverexample/App.css
.App { text-align: center; } .App-logo { height: 40vmin; pointer-events: none; } .App-header { background-color: #282c34; min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; font-size: calc(10px + 2vmin); color: white; } input { color: #000; } .App-link { color: #61dafb; }
Créez des composants pour récupérer et afficher la liste des utilisateurs :
src/app/serverexample/UserList.tsx
import { getUsers } from "@/actions/user"; import { UserDetail } from "./UserDetail"; export default async function UserList() { //Api call to fetch User details const users = await getUsers(); return ( <div classname="grid grid-cols-3 gap-5"> {users.length ? ( users.map((user) => <userdetail user="{user}"></userdetail>) ) : ( <div classname="col-span3 opacity-60 text-sm text-center"> No User found </div> )} </div> ); }
src/app/serverexample/UserDetail.tsx
export function UserDetail({ user }) { return ( <div classname="flex items-center gap-4 border border-gray-600 py-1 px-4"> <img src="/static/imghw/default1.png" data-src="https://api.dicebear.com/9.x/personas/svg?seed=Shadow" class="lazy" classname="w-10 h-10 rounded-full" alt="Réagir – Actions du serveur"> <div classname="font-medium text-base dark:text-white"> <div>{user.name}</div> <div classname="text-sm text-gray-500 dark:text-gray-400"> {user.email} </div> </div> </div> ); }
Exécutez le serveur de développement :
yarn dev
Accédez à http://localhost:3000/serverexample pour voir la liste des utilisateurs rendue :
Par défaut, les composants de Next.js sont des composants serveur sauf si vous spécifiez la directive "use client". Notez deux points importants :
- Définition des composants asynchrones : les composants du serveur peuvent être asynchrones car ils ne sont pas restitués et ne sont générés qu'une seule fois.
- Récupération de données : La ligne const users = wait getUsers(); récupère les données du serveur et les restitue au moment de l'exécution.
Explorer les actions du serveur
Les actions du serveur permettent une intercommunication client-serveur transparente. Ajoutons un formulaire pour créer de nouveaux utilisateurs.
Créez un nouveau fichier sur src/app/serverexample/AddUser.tsx :
"use client"; import "./app.css"; import { useActionState } from "react"; import { createUser } from "../../actions/user"; const initialState = { error: undefined, }; export default function AddUser() { const submitHandler = async (_previousState: object, formData: FormData) => { try { // This is the Server Action method that transfers the control // Back to the server to do DB operations and get back the result. const response = await createUser({ name: formData.get("name") as string, email: formData.get("email") as string, age: parseInt(formData.get("age") as string), }); return { response }; } catch (error) { return { error }; } }; const [state, submitAction, isPending] = useActionState( submitHandler, initialState ); return ( <div classname="mt-10"> <h4 id="Add-new-User">Add new User</h4>{" "} <form action="%7BsubmitAction%7D" classname="text-base"> <div classname="mt-6 text-right"> Name:{" "} <input classname="ml-2" required name="name" type="text" placeholder="Name"> </div> <div classname="mt-6 text-right"> Email:{" "} <input classname="ml-2" name="email" type="email" placeholder="Email"> </div> <div classname="mt-6 text-right"> Age:{" "} <input classname="ml-2" name="age" type="text" placeholder="Age"> </div> <div classname="mt-6 text-right"> <button disabled classname="bg-green-600 text-white px-5 py-1 text-base disabled:opacity-30"> {isPending ? "Adding" : "Add User"} </button> </div> {(state?.error as string) && <p>{state.error as string}</p>} </form> </div> ); }
Mettez à jour src/app/serverexample/page.tsx pour inclure le composant AddUser :
import UserList from "./UserList"; // Import new line import AddUser from "./AddUser"; import "./App.css" export default async function ServerPage() { return ( <div classname="app"> <header classname="App-header"> <userlist></userlist> {/* insert Add User here */} <adduser></adduser> </header> </div> ); }
L'exécution de l'application vous permettra désormais d'ajouter de nouveaux utilisateurs via le formulaire, avec un traitement côté serveur géré de manière transparente.
The AddUser Component and Seamless Client-Server Interaction
The AddUser component is at the heart of this example, showcasing how React Server Actions can revolutionize the way we handle client-server interactions. This component renders a form for adding new users and leverages the useActionState hook to create a smooth and seamless bridge between the client-side interface and server-side operations.
How It Works
- Form Rendering and Data Handling:
- The AddUser component provides a form where users can input their name, email, and age.
- Upon form submission, the data is captured and prepared to be sent to the server.
- useActionState Hook:
- The useActionState hook is a crucial part of this setup. It simplifies the complexity of managing client-side state and server-side actions by abstracting them into a unified interface.
- This hook accepts an asynchronous handler function, which processes the form data and then calls a Server Action method.
- The brilliance of this approach lies in its abstraction: it feels as though you’re invoking a regular function within the same file, even though it actually triggers a server-side operation.
- Server Action Method:
- The createUser function, defined as a Server Action, executes on the server side. It takes the user data from the form, performs the necessary database operations via Prisma, and returns the result.
- This server-side method is crucial for maintaining a clean separation between the client and server, while still enabling them to communicate effectively.
- Seamless Integration:
From the perspective of a developer working on the client side, it appears as if the form submission is handled locally. However, the heavy lifting such as database manipulation occurs on the server.
The useActionState hook encapsulates this process, managing the state transitions and handling errors, while maintaining an intuitive API for developers.
Server Actions Without Forms
So that's with forms, now lets test an example without forms.
update src/app/serverexample/UserDetail.tsx
"use client"; import { deleteUser } from "@/actions/user"; import { useTransition } from "react"; export function UserDetail({ user }) { const [pending, startTransition] = useTransition(); const handleDelete = () => { startTransition(() => { deleteUser(user.id); }); }; return ( <div classname="flex items-center gap-4 border border-gray-600 py-1 px-4"> {pending ? ( <p>Deleting...</p> ) : ( <img src="/static/imghw/default1.png" data-src="https://api.dicebear.com/9.x/personas/svg?seed=Shadow" class="lazy" classname="w-10 h-10 rounded-full" alt="Réagir – Actions du serveur"> <div classname="font-medium text-base dark:text-white"> <div>{user.name}</div> <div classname="text-sm text-gray-500 dark:text-gray-400"> {user.email} </div> </div> <button classname="ml-auto" onclick="{handleDelete}"> <img src="/static/imghw/default1.png" data-src="/delete.png" class="lazy" classname="w-4 h-4" alt=""> </button> > )} </div> ); }
Key Points:
- Server Action: deleteUser(user.id) is a server action that removes the user from the database. This operation is triggered without any form submission.
- useTransition: This hook allows you to manage the asynchronous state of the deletion process, showing a "Deleting..." message while the operation is in progress.
- User Interface: The component maintains a clean UI, dynamically updating based on the action status.
Now, you can seamlessly delete a user within the application:
Conclusion
This approach is transformative because it abstracts away the complexities of client-server communication. Traditionally, such interactions would require handling API endpoints, managing asynchronous requests, and carefully coordinating client-side state with server responses. With React Server Actions and the useActionState hook, this complexity is reduced, allowing developers to focus more on building features rather than worrying about the underlying infrastructure.
By using this pattern, you gain:
- Cleaner Code: The client-side code remains simple and focused, without the need for explicit API calls.
- Improved Developer Experience: Server-side operations are seamlessly integrated, reducing cognitive load and potential for errors.
- Enhanced Performance: Server Actions are optimized for performance, reducing unnecessary client-server round trips and ensuring that server-side resources are used efficiently.
You can find the full code in the repository
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds











Python convient plus aux débutants, avec une courbe d'apprentissage en douceur et une syntaxe concise; JavaScript convient au développement frontal, avec une courbe d'apprentissage abrupte et une syntaxe flexible. 1. La syntaxe Python est intuitive et adaptée à la science des données et au développement back-end. 2. JavaScript est flexible et largement utilisé dans la programmation frontale et côté serveur.

Les principales utilisations de JavaScript dans le développement Web incluent l'interaction client, la vérification du formulaire et la communication asynchrone. 1) Mise à jour du contenu dynamique et interaction utilisateur via les opérations DOM; 2) La vérification du client est effectuée avant que l'utilisateur ne soumette les données pour améliorer l'expérience utilisateur; 3) La communication de rafraîchissement avec le serveur est réalisée via la technologie AJAX.

L'application de JavaScript dans le monde réel comprend un développement frontal et back-end. 1) Afficher les applications frontales en créant une application de liste TODO, impliquant les opérations DOM et le traitement des événements. 2) Construisez RestulAPI via Node.js et Express pour démontrer les applications back-end.

Comprendre le fonctionnement du moteur JavaScript en interne est important pour les développeurs car il aide à écrire du code plus efficace et à comprendre les goulots d'étranglement des performances et les stratégies d'optimisation. 1) Le flux de travail du moteur comprend trois étapes: analyse, compilation et exécution; 2) Pendant le processus d'exécution, le moteur effectuera une optimisation dynamique, comme le cache en ligne et les classes cachées; 3) Les meilleures pratiques comprennent l'évitement des variables globales, l'optimisation des boucles, l'utilisation de const et de locations et d'éviter une utilisation excessive des fermetures.

Python et JavaScript ont leurs propres avantages et inconvénients en termes de communauté, de bibliothèques et de ressources. 1) La communauté Python est amicale et adaptée aux débutants, mais les ressources de développement frontal ne sont pas aussi riches que JavaScript. 2) Python est puissant dans les bibliothèques de science des données et d'apprentissage automatique, tandis que JavaScript est meilleur dans les bibliothèques et les cadres de développement frontaux. 3) Les deux ont des ressources d'apprentissage riches, mais Python convient pour commencer par des documents officiels, tandis que JavaScript est meilleur avec MDNWEBDOCS. Le choix doit être basé sur les besoins du projet et les intérêts personnels.

Les choix de Python et JavaScript dans les environnements de développement sont importants. 1) L'environnement de développement de Python comprend Pycharm, Jupyternotebook et Anaconda, qui conviennent à la science des données et au prototypage rapide. 2) L'environnement de développement de JavaScript comprend Node.js, VScode et WebPack, qui conviennent au développement frontal et back-end. Le choix des bons outils en fonction des besoins du projet peut améliorer l'efficacité du développement et le taux de réussite du projet.

C et C jouent un rôle essentiel dans le moteur JavaScript, principalement utilisé pour implémenter des interprètes et des compilateurs JIT. 1) C est utilisé pour analyser le code source JavaScript et générer une arborescence de syntaxe abstraite. 2) C est responsable de la génération et de l'exécution de bytecode. 3) C met en œuvre le compilateur JIT, optimise et compile le code de point chaud à l'exécution et améliore considérablement l'efficacité d'exécution de JavaScript.

Python est plus adapté à la science et à l'automatisation des données, tandis que JavaScript est plus adapté au développement frontal et complet. 1. Python fonctionne bien dans la science des données et l'apprentissage automatique, en utilisant des bibliothèques telles que Numpy et Pandas pour le traitement et la modélisation des données. 2. Python est concis et efficace dans l'automatisation et les scripts. 3. JavaScript est indispensable dans le développement frontal et est utilisé pour créer des pages Web dynamiques et des applications à une seule page. 4. JavaScript joue un rôle dans le développement back-end via Node.js et prend en charge le développement complet de la pile.
