React Server
Components

Client Apps (SPA)

  • Wait until all of the components are ready and then render them
  • Wait for everything
  • The html that's rendered is the container
  • JavaScript builds the rest
  • A lot of work is put on the server
document.getElementById("root");

GET / bundle.js

 

 

render when ready

Client Apps (SPA)

Benefits

 

  • Navigation without refresh
  • Strong separation between server and client responsibilities
  • Can achieve performance wins with lazy loading, code splitting, preloading

Drawbacks

 

  • The bigger the bundle, the slower the app
  • SEO Limitations
  • Need additional help with data fetching/caching

 

 

Server Side Rendering

React Workshop

Starting in 4 minutes

Topics

  • Props
  • State
  • Handling Data

Server Side Rendering

Benefits

 

  • Less JavaScript (probably)
  • SEO Enabled

Drawbacks

 

  • If you reload the page (data fetching, server generated time, etc.), you still need to wait for those.
  • Have to decide what is server rendered and isn't
  • Doesn't prevent the server from being slow

 

 

Server Components

 

How does this work?

Not everything is interactive, most can be server rendered

* React components are run on the server

* HTML output is sent directly as the source

Data Streaming Format

 

* string representation of the Virtual DOM

if there are client components, this describes where to insert at runtime

 

Reconciliation

 

Works similarly to handle updates

But console errors are thrown if there is a mismatch

 

benefits

move data fetching to the server

smaller bundle size

can refetch without getting rid of client side state

 

 

but... you're probably going to need a framework to see the benefits

 

Next.js

App Router - server components by default

opt in to client components with "use client"


If something is specified as a client component, it's still pre-rendered and included as static output -- SSR

 

Reconciliation still happens to diff the DOM created from static HTML with the virtual DOM

Next.js

When a route is loaded with Next.js, the initial HTML is rendered on the server. This HTML is then progressively enhanced in the browser, allowing the client to take over the application and add interactivity, by asynchronously loading the Next.js and React client-side runtime.

 

progressive enhancement

 

Show the users the content that is ready

load interactive or data-reliant content in the background

 

 

"use client"

 

place it above the imports

for example, if Menu imports MenuButton, MenuSlider, etc, it is assumed that these are also client components

  • Components in the Server Component module graph are guaranteed to be only rendered on the server.
  • Components in the Client Component module graph are primarily rendered on the client, but with Next.js, they can also be pre-rendered on the server and hydrated on the client.
  • The "use client" directive must be defined at the top of a file before any imports.
  • "use client" does not need to be defined in every file. The Client module boundary only needs to be defined once, at the "entry point", for all modules imported into it to be considered a Client Component.

server components don't read from React state

Which one should I use?

Client vs Server

useState, useEffect

Client!

Accessing backend resources

Server!

Browser only APIs

Client!

Auth details like tokens, API keys

Server!

Data Fetching

Server!

Event handlers (onClick, onChange)

Client!

RSC Do's and Do Not Do's

Make Client Components Leaves

Compose Client and Server Components

  • On the client, React renders Client Components and slots in the rendered result of Server Components, merging the work done on the server and client.
    • If any Server Components are nested inside a Client Component, their rendered content will be placed correctly within the Client Component.

Don't import server components in client components

Pass server components to client components as a prop

Keep client code out of server components

export async function loadData() {
  const res = await fetch('https://mh.com/pets', {
    headers: {
      authorization: process.env.API_KEY,
    },
  })
 
  return res.json()
}

What's the issue?

server-only

import "server-only";

export async function loadData() {
  const res = await fetch('https://mh.com/pets', {
    headers: {
      authorization: process.env.API_KEY,
    },
  })
 
  return res.json()
};

Error!

client-only

import "client-only";

function interactWithUserInWeirdAntiquatedWay() {
  window.prompt("How are you? ");
};

Incorporating Third Party Libraries

Using directly in a Server component might not work 

Can wrap in a client component to pass to server component

 

'use client'
 
import { MagicList } from 'magic-list';
 
export default List;

Context

(deep breaths)

Context of Our Youth

const App = function() {
  return (
    <Provider data={data}>
    	<Layout />
    </Provider>
  )
}

3rd party providers: Apollo, Redux, etc



Data Fetching

useEffect

Data Fetching

GraphQL  - useQuery, useMutation, useSubscription

React Server Components

By Moon Highway

React Server Components

  • 206