Using React with Django, do I need react-router?

Viewed 1621

Suppose I have an existing Django webapp with a bunch of urls in urls.py. Now suppose I want to add a number of webpages to this Django app, where the new webpages are built using React.

From what I understand, React has its own routing capability (in react-router) so that if I go to mydomain.com/page1/ it will serve one thing and if I go to mydomain.com/page2/ it will serve something else.

But what if I don't want to use react-router? In other words, if I have say 10 new pages to add and each page will have its own URL, then why can't I just set this up in Django's urls.py file?

Currently in urls.py I have a url defined like this:

url(r'^testview/', views.testview),

In views.py I define testview like this:

def testview(request):
    return render(request, 'testview.html', {})

My Django templates are stored in a folder BASE_DIR/myproject/templates/ and I set the TEMPLATES variable inside BASE_DIR/myproject/settings.py so Django knows where to find the templates. So in my view method above, testview.html refers to BASE_DIR/myproject/templates/testview.html. The contents of that file are:

{% extends "base.html" %}
{% load render_bundle from webpack_loader %}

{% block main %}
<div id="App1"></div>
{% render_bundle 'vendors' %}
{% render_bundle 'App1' %}
{% endblock %}

Finally, I defined App1 in App1.jsx as follows:

import React from "react"

import Headline from "../components/Headline"

    class App1 extends React.Component {
      render() {
        return (
          <div className="container">
            <div className="row">
              <div className="col-sm-12">
                <Headline>Hello There!</Headline>
              </div>
            </div>
          </div>
        )
      }
    }

This works fine, but what if I wanted to have 10 different pages? Would I need new app files like App2.jsx, App3.jsx, etc, one for each page?

Finally, suppose I want to pass a Django variable to my React app, for example:

def testview_with_time(request):
    now = datetime.datetime.now()
    return render(request, 'testviewtime.html', {
        'currtime': '%s' % str(now),
    })

Here I pass the variable currtime. How do I pass this into the React App1 class?

2 Answers

@Marc, I think you are on the right track with what's been given to you. I agree with @SrThompson's answer, but I'd make some slight changes:


Starting with Django. In your testview.html:

{% extends "base.html" %}
{% load render_bundle from webpack_loader %}

{% block main %}
<div id="{{component_name}}"></div>
{% render_bundle 'vendors' %}
{% render_bundle component_name %}
{% endblock %}

So, there would be a component_name context variable that defines the component being rendered by react and also sets the ID of the main div.


Jumping to React, you could have a render.js file that would be like this:

import React from 'react';
import ReactDOM from 'react-dom';
import App from '../somewhere';    

const render = Component => {
  ReactDOM.render(
    <App>
      <Component />
    </App>,
    document.getElementById(Component.name)
  )
}

export default render;

This render function takes the Component you passed as a parameter and renders it to the element with id='Component', just like you set in the context variable in Django. You also get the App component on top of every rendered component, just as a normal react app would work. Just call them using render(App1.jsx) for instance.


This way you would have to worry about creating only a single .hmtl file for rendering the react components.

react-router is a Frontend router meant to be used on Single Page Applications. If you're not building a SPA you don't need it.

You can hook up a react parent component anywhere you want, it's pretty flexible that way, but yes, if you want to go the server-side rendering way with your Django views and use react to enhance parts of it, then yes, you would need App2.jsx, App3.jsx, etc. (I would suggest picking better names though)

Also, if you're going this way, don't use react to build the full page, only use it where you need the extra interactivity, like a widget or something. If you're rendering the entire page in react without making the app a SPA you lose the benefits from both the JS client app and server-side rendering

You can't pass variables from django views to react components, because they're rendered on the browser. Whatever data you need in your react components has to be fetched with an AJAX request, just like any other JS library

Related