¿Qué son los componentes del servidor React?

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.





El discurso de Dan Abramov





Documentación RFC





Aplicación de muestra








All Articles