Reader small image

You're reading from  React and React Native - Fourth Edition

Product typeBook
Published inMay 2022
Reading LevelIntermediate
PublisherPackt
ISBN-139781803231280
Edition4th Edition
Languages
Right arrow
Authors (3):
Adam Boduch
Adam Boduch
author image
Adam Boduch

Adam Boduch has been involved in large-scale JavaScript development for nearly 15 years. Before moving to the frontend, he worked on several large-scale cloud computing products using Python and Linux. No stranger to complexity, Adam has practical experience with real-world software systems and the scaling challenges they pose.
Read more about Adam Boduch

Roy Derks
Roy Derks
author image
Roy Derks

Roy Derks is a serial start-up CTO, international speaker, and author from the Netherlands. He has been working with React, React Native, and GraphQL since 2016. You might know him from the book “React Projects – Second Edition”, which was released by Packt earlier this year. Over the last few years, he has inspired tens of thousands of developers worldwide through his talks, books, workshops, and courses.
Read more about Roy Derks

Mikhail Sakhniuk
Mikhail Sakhniuk
author image
Mikhail Sakhniuk

Mikhail Sakhniuk is Software Engineer with high proficiency in JavaScript, React and React Native. He has more than 5 years of experience in developing web and mobile applications. He has worked for startups, fintech companies, and product companies with more than 20 million users. Currently, Mikhail is working at Miro as a Frontend Engineer. In addition, he owns and maintains a few open-source projects. He also shares his experience and knowledge through books and articles.
Read more about Mikhail Sakhniuk

View More author details
Right arrow

Chapter 11: Server-Side React Components

Everything that you've learned so far in this book has been React code that runs in web browsers. React isn't just confined to the browser for rendering, and in this chapter, you'll learn how to render components from a Node.js server.

The first section of this chapter briefly touches upon high-level server rendering concepts. The next four sections go into more depth, teaching you how to implement the most crucial aspects of server-side rendering with React and Next.js.

In this chapter, we'll cover the following topics:

  • What is isomorphic JavaScript?
  • Rendering to strings
  • Backend routing
  • Frontend reconciliation
  • Fetching data

Technical requirements

You can find the code files present in this chapter on GitHub at https://github.com/PacktPublishing/React-and-React-Native-4th-Edition/tree/main/Chapter11.

What is isomorphic JavaScript?

Another term for server-side rendering is isomorphic JavaScript. This is a fancy way of saying JavaScript code that can run in the browser and in Node.js without modification. In this section, you'll learn the basic concepts of isomorphic JavaScript before diving into the code.

The server is a render target

The beauty of React is that it's a small abstraction layer that sits on top of a rendering target. So far, the target has been the browser, but it can also be the server. The render target can be anything, just as long as the correct translation calls are implemented behind the scenes.

In the case of rendering on the server, components are rendered to strings. The server can't actually display rendered HTML; all it can do is send the rendered markup to the browser. This idea is shown in the following diagram:

Figure 11.1 – A conceptual model of server-side rendering

It's possible to render...

Rendering to strings

When React components are rendered in Node.js, they're transformed into strings of HTML output. The string content is then returned to the browser, which displays this to the user immediately. Let's look at an example.

Here is the component to render:

import React from "react";
import PropTypes from "prop-types";
 
export default function App({ items }) {
  return (
    <ul>
      {items.map(item => (
        <li key={item}>{item}</li>
      ))}
    </ul>
  );
}
 
App.propTypes = {
  items: PropTypes.arrayOf(PropTypes.string).isRequired
};

Next, let's implement the server that will render this component when the browser asks for it:

import * as React from "react";
import ReactDOM from "react-dom/server"...

Backend routing

In the Rendering to strings section, you implemented a single request handler in the server that responded to requests for the root URL (/). Your application is going to need to handle more than a single route. You learned how to use the react-router package for routing in Chapter 9, Handling Navigation with Routes, but now, you're going to see how to use the same package in Node.js.

First, let's take a look at the main App component:

import { Routes, Route, Link, Outlet } from 
  "react-router-dom";
 
import FirstHeader from "./first/FirstHeader";
import FirstContent from "./first/FirstContent";
import SecondHeader from "./second/SecondHeader";
import SecondContent from "./second/SecondContent";
 
function Layout() {
  return (
    <section>
      <Outlet />
    </section>
  );
}
 
export...

Frontend reconciliation

The only thing that was missing from the last example was the client's JavaScript code. The user wants to use the application, and the server needs to deliver the client's code bundle. How would this work? Routing has to work in the browser and on the server, without modifying the routes. In other words, the server handles routing in the initial request and then the browser takes over as the user starts clicking on things and moving around in the application.

Let's create the index.js module for this example:

import React from "react";
import { hydrate } from "react-dom";
import App from "./App";
 
hydrate(<App />, document.getElementById("root"));

This looks like most other index.js files that you've seen so far in this book. You render the <App> component in the root element in the HTML document. In this case, you're using the hydrate() function instead of the render() function...

Fetching data

What if one of your components needs to fetch API data before it can fully render its content? This presents a challenge for rendering on the server because there's no easy way to define a component that knows when to fetch data on the server and in the browser.

This is where a minimal framework such as Next.js comes into play. Next.js treats server rendering and browser rendering as equals. This means that the headache of fetching data for your components is abstracted—you can use the same code in the browser and on the server.

To handle routing, Next.js uses the concept of pages. A page is a JavaScript module that exports a React component. The rendered content of the component turns into the page content. Here's what the pages directory looks like:

  • pages
    • first.js
    • index.js
    • second.js

The index.js module is the root page of the app; Next.js knows this based on the filename. Here's what the source looks like:

import Layout from...

Summary

In this chapter, you learned that React can be rendered on the server, in addition to the client. There are several reasons for doing this, such as sharing common code between the frontend and the backend. The main advantage of server-side rendering is the performance boost that you get on the initial page load. This translates to a better user experience and, therefore, a better product.

Then, you progressively improved a server-side React application, starting with a single-page render. You were also introduced to routing, client-side reconciliation, and component data fetching to produce a complete backend rendering solution using Next.js.

In the next chapter, you'll learn how to implement modern React UI components using Material UI.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
React and React Native - Fourth Edition
Published in: May 2022Publisher: PacktISBN-13: 9781803231280
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Authors (3)

author image
Adam Boduch

Adam Boduch has been involved in large-scale JavaScript development for nearly 15 years. Before moving to the frontend, he worked on several large-scale cloud computing products using Python and Linux. No stranger to complexity, Adam has practical experience with real-world software systems and the scaling challenges they pose.
Read more about Adam Boduch

author image
Roy Derks

Roy Derks is a serial start-up CTO, international speaker, and author from the Netherlands. He has been working with React, React Native, and GraphQL since 2016. You might know him from the book “React Projects – Second Edition”, which was released by Packt earlier this year. Over the last few years, he has inspired tens of thousands of developers worldwide through his talks, books, workshops, and courses.
Read more about Roy Derks

author image
Mikhail Sakhniuk

Mikhail Sakhniuk is Software Engineer with high proficiency in JavaScript, React and React Native. He has more than 5 years of experience in developing web and mobile applications. He has worked for startups, fintech companies, and product companies with more than 20 million users. Currently, Mikhail is working at Miro as a Frontend Engineer. In addition, he owns and maintains a few open-source projects. He also shares his experience and knowledge through books and articles.
Read more about Mikhail Sakhniuk