Hace apenas una semana, el equipo de reacción publicó en su blog sobre el nuevo RFC . Averigüemos qué tipo de animal es y por qué se necesita.
Qué es
Como su nombre lo indica, React Server Components son componentes que se ejecutan en el servidor. Ahora tenemos varios tipos de componentes:
Componentes del cliente
Componentes del servidor
Componentes híbridos
Componentes del cliente
, , . . .client.js
, ( useState
"" ). . . .server.js
. , .
. . . JSX .
SSR
, SSR
Next.js
. , ? . , SSR
HTML
, . SSR
, . Server Components JSON
virtual dom
.
, , server components.
SSR server components, .
, . , .
, , .server.js
// Note.server.js - Server Component
import db from 'db.server';
// (A1) We import from NoteEditor.client.js - a Client Component.
import NoteEditor from 'NoteEditor.client';
function Note(props) {
const {id, isEditing} = props;
// (B) Can directly access server data sources during render, e.g. databases
const note = db.posts.get(id);
return (
<div>
<h1>{note.title}</h1>
<section>{note.body}</section>
{/* (A2) Dynamically render the editor only if necessary */}
{isEditing
? <NoteEditor note={note} />
: null
}
</div>
);
}
.
, , :
Zero-Bundle-Size Components
, , . , , . , markdown , :
// NoteWithMarkdown.js
// NOTE: *before* Server Components
import marked from 'marked'; // 35.9K (11.2K gzipped)
import sanitizeHtml from 'sanitize-html'; // 206K (63.3K gzipped)
function NoteWithMarkdown({text}) {
const html = sanitizeHtml(marked(text));
return (/* render */);
}
bundle 74 , server components, :
// NoteWithMarkdown.server.js - Server Component === zero bundle size
import marked from 'marked'; // zero bundle size
import sanitizeHtml from 'sanitize-html'; // zero bundle size
function NoteWithMarkdown({text}) {
const html = sanitizeHtml(marked(text));
return (/* render */);
}
, 74 .
Backend
, :
// Note.server.js - Server Component
import fs from 'react-fs';
function Note({id}) {
const note = JSON.parse(fs.readFile(`${id}.json`));
return <NoteWithMarkdown note={note} />;
}
// Note.server.js - Server Component
import db from 'db.server';
function Note({id}) {
const note = db.notes.get(id);
return <NoteWithMarkdown note={note} />;
}
, , 3 :
react-fs
-
react-fetch
-
react-pg
- PostgresSql
, API server component.
Code Splitting
, Code Splitting. , , bundle React.lazy:
// PhotoRenderer.js
// NOTE: *before* Server Components
import React from 'react';
// one of these will start loading *when rendered on the client*:
const OldPhotoRenderer = React.lazy(() => import('./OldPhotoRenderer.js'));
const NewPhotoRenderer = React.lazy(() => import('./NewPhotoRenderer.js'));
function Photo(props) {
// Switch on feature flags, logged in/out, type of content, etc:
if (FeatureFlags.useNewPhotoRenderer) {
return <NewPhotoRenderer {...props} />;
} else {
return <OldPhotoRenderer {...props} />;
}
}
Server Components, :
// PhotoRenderer.server.js - Server Component
import React from 'react';
// one of these will start loading *once rendered and streamed to the client*:
import OldPhotoRenderer from './OldPhotoRenderer.client.js';
import NewPhotoRenderer from './NewPhotoRenderer.client.js';
function Photo(props) {
// Switch on feature flags, logged in/out, type of content, etc:
if (FeatureFlags.useNewPhotoRenderer) {
return <NewPhotoRenderer {...props} />;
} else {
return <OldPhotoRenderer {...props} />;
}
}
, , .
client-server
- , , , .
. , API. graphql/JSON API .
:
// Note.js
// NOTE: *before* Server Components
function Note(props) {
const [note, setNote] = useState(null);
useEffect(() => {
// NOTE: loads *after* rendering, triggering waterfalls in children
fetchNote(props.id).then(noteData => {
setNote(noteData);
});
}, [props.id]);
if (note == null) {
return "Loading";
} else {
return (/* render note here... */);
}
}
Note, . server components , :
// Note.server.js - Server Component
function Note(props) {
// NOTE: loads *during* render, w low-latency data access on the server
const note = db.notes.get(props.id);
if (note == null) {
// handle missing note
}
return (/* render note here... */);
}
Por lo tanto, cuando un componente se ejecuta en el servidor, puede interactuar con la API necesaria y transferir datos al componente en una iteración a través de la red para el usuario, después de lo cual el resultado de la ejecución del componente se transmite al usuario.
Salir
En mi opinión, los componentes del servidor tienen lugar, la combinación de suspensión, modo concurrente y componentes del servidor puede ser flexible para los desarrolladores y fácil de usar para implementar la interfaz de usuario.
No olvide este RFC y el enfoque, las implementaciones y las API pueden cambiar antes del lanzamiento oficial.
¿Qué opinas sobre los componentes del servidor?
Material adicional
Si desea profundizar en los componentes del servidor con más detalle.