Toni
Les 'Server Actions' són una característica recentment introduïda a la tecnologia que permet l'execució de codi directament al servidor des de qualsevol client sense la necessitat de crear un punt d'API separat.
Simplificant al màxim, podem invocar funcions definides al codi del servidor prement un botó al nostre navegador, entre molts altres casos.
Ara us ensenyarem com aprofitar aquesta funcionalitat amb casos d'ús reals que hem aplicat nosaltres en aquest mateix web.
Les 'Server Actions' són funcions que s'executen al servidor i es poden invocar des del client. Aquesta funcionalitat és un avanç significatiu ja que elimina la necessitat de crear punts d'API dedicats com s'havia de fer a versions anteriors.
Amb aquesta eina, els desenvolupadors tindrem una nova experiència de desenvolupament que sens dubte revolucionarà i agilitzarà els nostres processos de treball.
Per ser precisos, les 'Server Actions' no són específiques de Next.js, sinó que en realitat són una funcionalitat incorporada de React, tot i que encara es troba en fase alfa. Per tant, si decidiu utilitzar-les, heu de saber que en qualsevol moment es podria modificar la seva implementació i/o la seva funcionalitat.
Són molt versàtils i es poden utilitzar per a diversos casos d'ús. Us donem alguns exemples:
Aquest nou concepte ofereix una gran quantitat d'avantatges i segurament descobrireu diversos casos d'ús on es poden aprofitar de manera efectiva.
Si en teniu d'interessants, feu-nos-los arribar :).
Ens posem en matèria, les podem definir en qualsevol lloc del nostre codi, amb algunes excepcions.
Cal tenir en compte que les 'Server Actions' només es poden definir al codi del servidor, ja sigui en un 'Server Component' o en un fitxer, però en cap cas es poden definir en un 'Client Component'. Aquests només poden importar 'Server Actions' per utilitzar-les.
Abans de començar, ens hem d'assegurar d'haver habilitat les 'Server Actions' al fitxer next.config.js
, com podeu veure és una funcionalitat experimental, com ja us hem dit anteriorment.
module.exports = {
experimental: {
serverActions: true,
}
};
Tot el que hem de fer és declarar una funció asíncrona amb la directiva use server
. Com ho fem nosaltres amb el nostre component de Blogs.
async function fetchBlogs(page) {
'use server';
return await get(BLOGS, { start: page * limit, limit: limit });
}
const Blogs = async ({ start = 0, limit = 12 }) => {
const blogs = await get(BLOGS, { start: start, limit: limit });
return (
<BlogsPager
blogs={blogs}
fetchBlogs={fetchBlogs}
/>
);
}
Hem de tenir en compte que les 'Server Actions' han de tenir arguments i valors de retorn serialitzables, com s'especifica en el concepte de 'Server Components' de React. Això és necessari perquè el valor de retorn de la funció es serialitza i s'envia al client.
Alternativament, podem definir les nostres 'Server Actions' des d'un fitxer, com podria ser /server-actions.js
, i afegir la directiva use server
a la part superior del fitxer.
'use server'
export async function laMevaServerAction() {
// Realitzeu les accions
}
export async function unaAltraServerAction() {
// Realitzeu les accions
}
Tenim diverses opcions per invocar-les.
Ho aconseguirem utilitzant la propietat action
o onSubmit
de l'element form. Nosaltres ho apliquem en una combinació amb 'Graphql' per crear els missatges que ens envieu des del formulari de contacte del web. No dubteu en utilitzar-ho :)
async function createMessage(name, email, message) {
'use server';
return await post(
`mutation createMessage($message: MessageInput!) {
createMessage(data: $message) {
data {
id
}
}
}`,
{ message: { name: name, email
: email, message: message }}
);
};
<form action={createMessage}>...</form>
Utilitzarem la propietat onClick
de l'element button.
// Query Graphql
const BLOGS = `
query Blogs($start: Int!, $limit: Int!) {
posts(sort: ["Rank:asc", "updatedAt:desc"], pagination: { start: $start, limit: $limit }) {
data {
attributes {
Title,
Briefing,
}
}
}
}
`
// 'Server Action'
async function fetchBlogs(page) {
'use server';
return await get(BLOGS, { start: page * limit, limit: limit });
}
// 'Server Component'
const Blogs = async ({ start = 0, limit = 12 }) => {
const blogs = await get(BLOGS, { start: start, limit: limit });
return (
<BlogsPager
blogs={blogs}
fetchBlogs={fetchBlogs}
/>
);
}
// 'Client Component'
'use client';
const BlogsPager = ({ blogs, fetchBlogs }) => {
// La nostra lògica ...
return (
<button
onClick={ async () => {
const newBlogs = await fetchBlogs(page);
setBlogs([...blogs, [...newBlogs?.data?.posts.data]]);
}}
>...</button>
)
}
En cas que vulguem invocar una 'Server Action' en algun altre punt del nostre codi que no sigui un formulari, un botó o un input, utilitzarem el hook
de React useTransition
.
'use server';
export async function afegirItem(id) {
await afegirBd(id);
revalidatePath('/item/[id]');
}
'use client';
import { useTransition } from 'react';
import { afegirItem } from '/server-actions.js'
function ClientComponent({ id }) {
const [ isPending, startTransition ] = useTransition();
return (
<button onClick={() => startTransition(() => afegirItem(id))}>...</button>
);
}
Si després d'invocar una 'Server Action' volem actualitzar les dades associades a una ruta específica de la nostra web, podem utilitzar la funció revalidatePath
.
Quan utilitzem 'Server Actions' des d'un formulari, aquestes continuaran funcionant fins i tot si JavaScript està deshabilitat, ja que el formulari s'enviarà al servidor. A la inversa, quan invoquem codi de forma imperativa només funcionarà quan JavaScript estigui habilitat.
Sempre que sigui possible, recomanem utilitzar 'Server Actions' des de formularis per garantir que la vostra aplicació funcioni fins i tot amb JavaScript deshabilitat.
Next.js defineix les 'Server Mutations' com a 'Server Actions' que muten dades i invoquen a redirect
, revalidatePath
o revalidateTag
.
Si no invoqueu cap d'aquestes funcions, no és necessari que marqueu la funció com a 'Server Mutation'.
async function createMessage(name, email, message) {
'server mutation';
await post(
`mutation createMessage($message: MessageInput!) {
createMessage(data: $message) {
data {
id
}
}
}`,
{ message: { name: name, email: email, message: message }}
);
redirect('/gracies');
}
Les 'Server Actions' són una característica potent que ens permet executar codi al servidor directament des del client sense la necessitat de crear punts d'API dedicats.
Poden ser utilitzades per a diverses accions, com mutar dades, realitzar lògica de servidor o invocar APIs externes. Amb aquesta nova funcionalitat, podem agilitzar els nostres processos de desenvolupament i millorar la experiència de l'usuari.
Cal tenir en compte que les 'Server Actions' es troben en fase alfa
i poden canviar en futurs llançaments de React.
No obstant això, podem aprofitar aquesta funcionalitat i explorar-ne els beneficis que ens ofereix avui dia. Esperem que aquesta explicació us sigui d'utilitat per aprofitar al màxim aquesta nova característica de Next.js.