A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://hackernoon.com/reconciling-djangos-mvc-templates-with-react-components-3aa986cf510a below:

Reconciling Backend Templates with Frontend Components

How to build a frontend without making a Single-Page-App

At $startupNameHere we decided to write our backend in Django and our frontend in React. The combination is not unusual these days, but if you’ve ever tried it you’ve probably found there’s some friction between page composition with backend templating systems, and React’s component model.

The fundamental issue is that Django wants you to build up your pages using template fragments, and React wants to pull you into its world with JS components as the main building blocks. This conflict can also arise with Rails, Flask and any other backend framework that uses templating.

I’m here to tell you these don’t necessarily have to conflict, it’s possible to use both without angering the Lilliputians.

Abandon SPA, embrace page-as-a-component

Our solution was to abandon the single page app model, and instead let Django serve each page individually, with a root React component for each page. Our base site components that don’t change between pages (e.g. navbar, footer) are provided by the Django templates, and the content specific to each page (e.g. poker interface, leaderboard) are composed within React.

Abandon the SPA, why would you say such a horrible thing?!

So what does this look like in practice?

The Django Template

Here we have our base template used for React pages, notice how it extends ui/base.html (which contains our header, navbar, and all the usual things you put in a base template).

This base template can accept any combination of JS component file and props. If you wanted you don’t even have to pass a React component, you could pass in a Vue.js or Angular script, and have it render to window.react_mount and read window.props.

But this page is empty, how do I render my React components?

The {{component}} is a path to a script, e.g. leaderboard.js, which contains a standard React component, rendered using ReactDOM. The script should be compiled and readily accessible by browsers from your staticfiles folder. It can be aggressively cached by your backend and nginx, since the contents never change, all dynamic content is passed via window.props.

So far this gives us a basic page with a navbar, and a loading message. Once we have a component to mount, the loading message is replaced by the component (this process happens so fast your users will never see the Loading Components… message).

The React Component

Now we define a basic React component which lays out our page. We can import reusable components from other JS files, or just write it all in one file. I’ll do that here for simplicity. A more complex page may mount a redux Provider, import dozens of components, or setup websocket connections here. Think of this as your ‘base.js’ entry point, similar to an SPA base.js, except it only defines the contents of one page.

Here I implement a simple leaderboard, which shows a list of users.

Building the Javascript Component

We compile this source file from ES6 to ancient JS using browserify, and stick it in our staticfiles folder so it can be served (and cached) easily. I chose browserify for simplicity, but you can use webpack in your project and get the same results.

browserify src/pages/leaderboard.js > static/src/pages/leaderboard.js

Great, now we have something on the screen!

But where did Alice & Bob come from, how did we pass data to the template?

The View

The Django view just needs to provide the following context to the react_base.html template in order to render this page properly:

  1. component = leaderboard.js (our React file above)
  2. props = {users: [{username: ‘alice’}, {username: ‘bob’}]} (the data passed to the React component as props)
  3. title = ‘Leaderboard’ (used for the browser tab title)
Why use this pattern, are there alternatives?

This simple pattern of mounting components inside of a base template which passes things to React is very powerful. It lets you freely mix and match template composition with React components, depending on which you need for a given page.

But we already built our whole frontend on top of an intricate REST API with endpoints for everything from user info to page content, why is this better?

Don’t go and rewrite your whole frontend if you already have a REST API-based SPA. You get some advantages with REST API + SPA that you don’t get with page-as-a-component, such as reduced bundle sizes because webpack can optimize shared code across pages. It might also be easier to scale if you split your backend functionality into separate micro-services. The page-as-a-component approach is great if you’re ok with slightly larger bundles, in order to get flexibility and nice interplay with Django templates and routing.

What are my options if I’m building an app from scratch these days?

Extending the Page-as-a-Component pattern

Ok, the Lilliputians are satisfied with the design, but they want more features!

The code samples above are overly simplified. A real app in 2017+ probably mounts Redux providers, creates WebSocket connections, fetches content over the wire, and imports many dozens of components to assemble a full page.

Now that I’ve introduced a basic pattern, it’s time to think about extending it with the next layers of functionality. Depending on your application you may decide to add:

You can ping me on twitter @theSquashSH if you have any questions, or check out our site in action at https://oddslingers.com!

In our app (a poker site) we use django-channels to send data over a WebSockets to a react-redux frontend. The frontend animates some game state in real-time, while remaining time-synchronized with all the other site viewers to within ~25ms. We didn’t find any libraries that pulled off web animation in a way that we liked, so we ended up implementing our own: [redux-time](https://github.com/Monadical-SAS/redux-time). It’s worth checking out if you’re trying to do real-time animation in a functional, declarative way with redux-style state management. We also developed [django-channels-router](https://github.com/Monadical-SAS/django-channels-router) which is the backend routing to handle socket messages to/from the frontend. Let me know if you find either library useful, or if you’ve worked on anything similar in the past!

Links and Resources:

tl;dr let Django manage your routing, make separate JS files for each page, pass props data to your components via the template

Hopefully you find this useful! If so, give this article a 💚, or ping me on twitter @theSquashSH.

If you’re interested working on cool Django + React/Redux projects involving Ethereum, Monadical is hiring remote & local devs (we’ll fly you to sunny Medellín for the first month)!


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4