Um guia de React Server Components

O que é React Server Components?

React Server Components é uma feature experimental do React, anunciada no blog do React.js em 21 de Dezembro de 2020.
No momento (25/02/2021) ainda não está pronto para produção.

useEffect(() => {
axios.get("ENDEREÇO AQUI")
.then((response) => {
// set data into state
setData(response.data);
})
.catch((error) => {
console.log(error);
});
}, []);

Como funciona?

Como essa feature do React ainda está em fase de experimentação, recomendo assistir a live explicando o conceito do React Server Components, pois a implementação pode mudar com o tempo.

"react": "0.0.0-experimental-3310209d0",
"react-dom": "0.0.0-experimental-3310209d0",
"react-fetch": "0.0.0-experimental-3310209d0",
"react-fs": "0.0.0-experimental-3310209d0",
"react-pg": "0.0.0-experimental-3310209d0",
"react-server-dom-webpack": "0.0.0-experimental-3310209d0",
  • .client.js indica um React Client Components
  • O habitual .js , pode ser rodado no client ou no server. Dependendo de quem o importa. Também serve para Shared Components. Por exemplo se você importa um Shared Component no server, ele atuará como Server Component, se você importa ele no Client, Será um Client Component.
  • O build do Webpack rodando o bundle client-side do React, usando o script scripts/build.js
const ReactApp = require('../src/App.server').default;
const {pipeToNodeWritable} = 
require('react-server-dom-webpack/writer');
async function renderReactTree(res, props) {
await waitForWebpack();
const manifest = readFileSync(
path.resolve(__dirname, '../build/react-client-manifest.json'),
'utf8'
);
const moduleMap = JSON.parse(manifest);
pipeToNodeWritable(React.createElement(ReactApp, props), res, moduleMap);
}

Bundle de tamanho Zero

O código dentro da extensão .server.js incluindo suas dependências , não é incluindo no bundle do client. Isso significa que tem zero efeito no tamanho do bundle.

//markdown.jsimport marked from 'marked'; // 37.38KBimport sanitizeHtml from 'sanitize-html'; // 208 KBexport default function TextwithMarkdown({Text}) {
return(
<div className="text-markdown"
dangerousSetInnerHTML={{
__html: sanitizeHtml(marked(text)),
}}
/>
);
}
// markdown.server.jsimport marked from 'marked'; // 0KBimport sanitizeHtml from 'sanitize-html'; // 0KBexport default function TextwithMarkdown({Text}) {
return(
<div className="text-markdown"
dangerousSetInnerHTML={{
__html: sanitizeHtml(marked(text)),
}}
/>
);
}

Acesso do backend ao banco de dados:

Server Components tem acesso direto ao banco de dados ou ao filesystem no servidor. Você pode pegar qualquer dado que você quiser e mandar para o client, no primeiro render:

export default function NoteList({searchText}) {
const notes = db.query(
`select * from notes where title ilike $1 order by id desc`,
['%' + searchText + '%']
).rows;


return notes.length > 0 ? (
<ul className="notes-list">
{notes.map((note) => (
<li key={note.id}>
<SidebarNote note={note} />
</li>
))}
</ul>
) : (
<div className="notes-empty">
{searchText
? `Couldn't find any notes titled "${searchText}".`
: 'No notes created yet!'}{' '}
</div>
);
}

Restrições

Assim como os Server Components são estáticos e renderizados no backend, eles tem algumas restrições de como podem ser usados.

//Page.server.js// import de componente interativo do client
import Button from '.Button.client.js';
export default Page() {
// data fetch, processamento, outras coisas..
return(
// use o <Button /> e outros componentes interativos aqui
);
}

Rotas

Analizando o projeto no demo no github, as rotas são setadas direto no arquivo api.server.js, onde literalmente, você constroi uma api como quiser, algo que o Next.js também tem como feature, seja fazendo sua própria Api server-side, ou refletindo na pasta /api

Quais as vantagens?

No começo parece muito com Server-Side Rendering (SSR). Na verdade oferece vantagens muito similares:

  • Melhor performance, pois evitamos a latência de rede entre servidor e cliente.
  • Menor tamanho do bundle. Libs que forem usados só no servidor não precisam ser usados no client : (como loadash, rambda, moment,e etc.), além dos Server Components nunca serem incluidos no bundle, e lidos pelo client.
  • Segurança: Fazer queries no lado do servidor sempre é mais seguro que no client. Além de não expor as requisições
  • Pode fazer queries GraphQL
  • Pode acessar diretamente bancos de dados PostgreSQL com o package react-pg
const MyComponent = React.lazy(() => import('./MyComponent.js'));
import MyComponent from './MyComponent.client.js';

Como os Server Components são diferentes de SSR (ex: Next.js)?

Utilizamos SSR hoje no React, apenas para que os componentes sejam renderizados como HTML no client, para que sua aplicação pareça ter uma resposta muito rápida. Seu usuário não consegue fazer nada na sua aplicação até que o JavaScript seja baixado.

M1:{"id":"./src/SearchField.client.js","chunks":["client5"],"name":""}

Server Component x Client Components

Vamos considerar o exemplo de uma aplicação que tem uma barra de busca para filmes, linkada a um banco de dados do seu backend. Vamos considerar que os resultados são um React Server Component, não um component comum (client), no caso do client component isso iria ocorrer:

  1. Assim que você recebe a resposta, você parseia o JSON, e manda pro React.
  2. O React renderiza os dados, e mostra as informações do filme na tela.
  1. O componente é renderizado no próprio servidor, e você recebe um build do markup estático, sem ser JSON ou HTML , como abaixo: M1:{“id”:”./src/SearchField.client.js”,”chunks”:[“client5”],”name”:””}
  2. O frontend (client), renderiza esse markup, como um UI estático ( importante: não um componente React), isso salva processamento adicional do componente no front-end.

Conclusão

React Server Components é uma nova abordagem de como construímos nossas aplicações React.
Pode mudar toda forma como o mercado utiliza o framework, e abre um leque de possibilidades em questão de performance, segurança e organização de código.
Por enquanto, podemos apenas brincar e testar, não sendo recomendado usar em produção.
A thread oficial no github tem a discussão da feature e do conceito, e muitas pessoas estão participando dando sugestões, críticas e idéias, e você também pode participar. Sugiro caso conheça inglês também ler os artigos linkados abaixo.

Com conteúdo traduzido de:

Bits and Pieces — React Server Components por Nathan Sebhastian
An Introduction to React Server Components por Nilanth
React Server Components Explained por Mehul Mohan

Links Úteis:

React Server Components — Addy Osmani
React Server Components Github Demo
React Server Components Video Explicação
Post no Blog do React sobre React Server Components

Software Engineer | Front-end Specialist @ Grover (https://rubenmarcus.dev)

Software Engineer | Front-end Specialist @ Grover (https://rubenmarcus.dev)