Il y a à peine une semaine, l'équipe de réaction a publié sur son blog un article sur la nouvelle RFC . Voyons de quel type d'animal il s'agit et pourquoi il est nécessaire.
Qu'Est-ce que c'est
Comme son nom l'indique, les composants React Server sont des composants qui s'exécutent sur le serveur. Nous avons maintenant plusieurs types de composants:
Composants clients
Composants du serveur
Composants hybrides
Composants clients
, , . . .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... */);
}
Ainsi, lorsqu'un composant est exécuté sur le serveur, il peut interagir avec l'API nécessaire et transférer des données vers le composant en une itération sur le réseau pour l'utilisateur, après quoi le résultat de l'exécution du composant est transmis à l'utilisateur.
Résultat
À mon avis, les composants de serveur ont une place pour être, la combinaison de la suspension, du mode simultané et des composants de serveur peut être flexible pour les développeurs et facile à utiliser pour implémenter l'interface utilisateur.
N'oubliez pas cette RFC et l'approche, les implémentations et les API peuvent changer avant la publication officielle.
Que pensez-vous des composants serveur?
Matériels supplémentaires
Si vous souhaitez vous plonger plus en détail dans les composants du serveur.