Hello React4XP

Contents

Your first React4XP page - and how it works

Movie DB dataset

This tutorial is dedicated to front-end development. To make it as compact as possible, we have pre-installed an application called the Headless Movie DB. It contains pre-defined CMS schemas as well as sample content and previews. We’ll be using this dataset extensively throughout the tutorial.

Visit our getting started guide, or the developer 101 tutorial to learn about schemas and content creation.

Add app to site

Follow these steps to make your application a front-end for the Headless Movie DB.

  1. Visit localhost:8080/admin. Log in and open Content Studio.

  2. The "Headless Movie Database" project should automatically be visible

  3. Select the root item in the tree structure, and you should see something like this:

    hmdb

  4. Click btn:[Edit], and connect your React4xp app to the site.

    add to site

    After saving, the preview should change to something like this:

    hello

Request handling

What happened?

By adding the application to the site, it is injected into the Site Engine’s request pipeline - it basically hijacks the rendering - taking presdence over HMDB’s built-in preview.

This is the basic execution flow that renders the page:

-> site/app.ts (HTML boostrapping)
  -> react4xp/entries/App.tsx (React entry)
    -> react4xp/dataFetcher.ts (Map of data processors)
      -> react4xp/components/hello/helloProcessor.ts (Fetch props for the Hello component)
    -> react4xp/componentRegistry.tsx (Map of React components)
      -> react4xp/components/hello/Hello.tsx (The Hello component)

Let’s have a look at the various files

Hello component

The component that rendered the page is very simple:

react4xp/hello/components/Hello.tsx
import type {HelloProps} from '/types/HelloProps';
import * as React from 'react';
import styles from './Hello.module.css';

export const Hello = ({title, initialCount}: HelloProps) => {
    const [count, setCount] = React.useState(initialCount);

    return (
        <div>
            <section className={styles.helloContainer}>
                <h1>{title}</h1>
                <button onClick={() => setCount(count + 1)}>{count} Clicks!</button>
            </section>
        </div>
    );
};

It takes a single parameter, HelloProps. The type is declared like this:

types/HelloProps.ts
export interface HelloProps {
    title: string
    initialCount: number
}

The Component Registry

To be triggered, the component was added to the ComponentRegistry.

react4xp/componentRegistry.ts
import {ComponentRegistry} from '@enonic/react-components';
import {Hello} from './components/Hello';

export const componentRegistry = new ComponentRegistry();

componentRegistry.addContentType('portal:site', { View: Hello }); (1)
1 The Hello component is mapped to the content type portal:site, which means it will be executed whenever the URL matches a site.
Try clicking other content items in Content Studio, and you should simply see an error message.

HelloProcessor

The responsibility of HelloProcessor is to produce the props required by a specific component.

react4xp/components/hello/HelloProcessor.ts
import {PageDescriptor} from '@enonic-types/core';
import type {ComponentProcessorFunction} from '@enonic-types/lib-react4xp/DataFetcher';

export const helloProcessor: ComponentProcessorFunction<PageDescriptor> = (params) => {
    return {
        title: `${params.content.displayName}`,
        initialCount: 0,
    };
};

Data Fetcher

Similar to the Component Registry, the DataFetcher is a registry of functions that will fetch data for a specific component. Unlike the React Components which can execute both on server and client, the dataFetcher is solely executed on the server, in order to fetch props for the various components.

Each processor is only invoked when needed by the current page. In this case if a site content is rendered.

react4xp/dataFetcher.ts
import {DataFetcher} from '/lib/enonic/react4xp';
import {helloProcessor} from './components/HelloProcessor';

export const dataFetcher = new DataFetcher();

dataFetcher.addContentType('portal:site', { processor: helloProcessor });

App component and controller

App.tsx (the app component) is responsible for setting up the application layout, like header and footer, and then invoking the dataFetcher and componentRegistry. We’ll get back to it later in this tutorial.

App.ts (the app controller) is responsible for HTML boostrapping and setting up React. We will not dive into this in the tutorial, but more details can be found in the app controller appendix.

Next

Great, you rendered your first page, next up how about setting up the application level components.


Contents

Contents

AI-powered search

Juke AI