Connecting React components with Django
richie
is a hybrid app, that relies on both HTML pages generated by the backend (Django/DjangoCMS) based on templates, and React components rendered on the frontend for parts of these HTML pages.
Rendering components
We needed a convention that enables us to easily mark those areas of the page that React needs to take control of, and to tell React which component to load there.
We decided to use a specific CSS class name along with its modifiers. We reserve the richie-react
class and its modified children for this purpose.
Additionally, components including internationalized data or strings need to know which locale to use. They will pick up the locale specified through the lang
attribute of the <html>
element, which is a requirement to have an accessible page anyway.
They use the BCP47/RFC5646 format.
<html lang="en-US">
Example
Here is how we would call a <FeaturedCourses />
component from a template, a plugin or a snippet:
<div
class="richie-react richie-react--featured-courses"
></div>
When our JS is loaded, it will recognize this as an element it must take over, and render the FeaturedCourses component in this element.
Passing properties to components
Some of Richie's React components, and some of those you might want to write, require arguments or "props" to be passed to them. We could work around that by adding API routes to fetch these props, but that would add complexity and reduce performance.
Instead, we decided to normalize a simpler way for components in Richie to accept input from the Django template that is adding them to the DOM.
We can add a data-props
attribute on the element with the richie-react
class and write a JSON object as the value for this attribute. Each key-value pair in this object will be passed as a propName={propValue}
to the React component.
Example
Here is how we would pass a categories={[ "sociology", "anthropology" ]}
prop to our <FeaturedCourses />
component:
<div
class="richie-react richie-react--featured-courses"
data-props='{"categories": ["sociology", "anthropology"]}'
></div>
When the component is rendered, it will be passed a categories
prop with the relevant categories.
Built-in components
Here are the React component that Richie comes with and uses out of the box.
<RootSearchSuggestField />
Renders a course search bar, like the one that appears in the default Search
page.
Interactions will send the user to the courseSearchPageUrl
url passed in the props, including the selected filter and/or search terms.
It also autocompletes user input with course names and allows users to go directly to the course page if they select a course name among the selected results.
Props:
courseSearchPageUrl
[required] — URL for the course search page users should be sent to when they select a suggestion that is not a course, or launch a search with text terms.context
[required] — see context.
<Search />
Renders the full-page course search engine interface, including the search results, and filters pane, but not the suggest field (which can be added separately with <SearchSuggestField />
) nor the page title.
NB: the Search
Django template basically renders just this page. If you need this, use it instead. It is included here for completeness' sake.
Props:
context
[required] — see context.
<SearchSuggestField />
Renders the course search bar that interacts directly with <Search />
.
It automatically communicates with <Search />
through browser history APIs and a shared React provider. This one, unlike <RootSearchSuggestField />
, is meant to be used in combination with <Search />
(on the same page).
Props:
context
[required] — see context.
<UserLogin />
Renders a component that uses the /users/whoami
endpoint to determine if the user is logged in and show them the appropriate interface: Signup/Login buttons or their name along with a Logout button.
Props:
loginUrl
[required] — the URL where the user is sent when they click on "Log in";logoutUrl
[required] — a link that logs the user out and redirects them (can be the standard django logout URL);signupUrl
[required] — the URL where the user is sent when they click on "Sign up".
Context
All built-in components for Richie accept a context
prop, that may be required or optional, depending on the component.
It is used to pass app-wide contextual information pertaining to the current instance, deployment or theme of Richie.
{
assets: {
// SVG sprite used throughout Richie
icons: "/path/to/icons/sprite.svg"
}
}
Note that it might be expanded in further versions of Richie.