Render a React component

Prerequisite: make sure you have followed the Project Setup before going further. You should have installed npm dependencies with npm install.

We would like to isolate the <h1>Hello World</h1> block inside a React component and then render it on our browser through the frontend pipeline. So let’s dive in to the frontend folder and understand how a component is delivered in our development setup.

    ├── public
    │   ├── bootstrap.min.css   <- A CSS library, check it on Google !
    │   └── index.html          <- Entry point for the frontend.
    ├── .prettierrc             <- Config for the prettier module.
    ├── package.json
    ├── package-lock.json       <- Generated by npm install with pinned versions
    ├── node_modules
    ├── tsconfig.json           <- Config for Typescript.
    └── src
        ├── index.tsx           <- Main entry point for React
        ├── MyComponent.tsx     <- Your component code
        └── react-app-end.d.ts  <- More config

Since we’re working with frontend code, we need to deliver it from a web server. The template comes with a development Webpack dev server preconfigured for your needs, with hot-reloading and compilation of React code / Typescript / ES6 on the fly.

You can start the dev server with a npm command from inside the frontend folder, where package.json is :

$ cd frontend
$ npm run start  # runs the `start` script command in package.json

This will start a local web server on port 3001. Now you can open your local browser (e.g., Firefox, Chrome, Edge) to http://localhost:3001 to see what this web browser delivers and … nothing!

Sadly, the Web page on your browser will be blank, though it should not return a 404 error. The reason is that the current template configuration causes the local web server to send an empty HTML with some JavaScript from the MyComponent component. The issue here is the component from the template only renders when it receives a particular Streamlit event, which you are not sending if you directly access the web server with your browser.

Browse the code with your favorite editor (e.g., PyCharm,Vs Code, etc.) and edit frontend/src/index.tsx so that the <h1>Hello World</h1> block is next to the non-rendered MyComponent element.

import React from "react";
import ReactDOM from "react-dom";
import MyComponent from "./MyComponent";

ReactDOM.render(
  <React.StrictMode>
    <h1>Hello world</h1>
    <MyComponent />
  </React.StrictMode>,
  document.getElementById("root")
);

The web server comes with live reloading, so your browser on http://localhost:3001 should update on-the-fly:

Hello world

For your understanding, the frontend/src/index.tsx injects itself into the <div id="root"></div> block within frontend/public/index.html. The dev webserver then sends the compiled index.html. Right now, you see the contents of frontend/src/index.tsx, which comprises of a heading “Hello world” and an invisible React component MyComponent.

Push the H1 block into a Dedicated Functional Component

  • Before continuing, let’s rename frontend classes to CustomSlider. In frontend/src, rename MyComponent.tsx to CustomSlider.tsx
  • Then remove the <h1> block and add a CustomSlider instance in frontend/src/index.tsx.
import React from "react";
import ReactDOM from "react-dom";
import CustomSlider from "./CustomSlider";

// Return your newly created CustomSlider
ReactDOM.render(
  <React.StrictMode>
    <CustomSlider />
  </React.StrictMode>,
  document.getElementById("root")
);

Now overwrite frontend/src/CustomSlider.tsx to return a <h1>Hello world</h1> block. This defines a functional component, where we use a function to return the frontend code to render.

import React from "react";

/**
 * Called by <CustomSlider />, renders the return value on screen.
 *
 * (props) => {code} is an arrow function, a shorter syntax for JS functions
 * equivalent to : function (props) { code; return <h1>Hello world</h1>};
 * or in Python, lambda props : return <h1>Hello world</h1>.
 *
 * When called, it will run then render on the browser the returned JSX block
 */
const CustomSlider = () => {
  // This React component returns (and renders) this <h1> block
  return <h1>Hello world</h1>;
};

// Make the function publicly available. If you forget this, index.tsx won't find it.
export default CustomSlider;

If your server experiences issues due to the file renaming, restart npm run start. A look at http://localhost:3001 will still display the <h1> block, but this time it will be coming from the CustomSlider component. We have removed all Streamlit classes which blocked the render by waiting for a particular JS event.

In the next section we will put back the code to connect the render to a Streamlit app.