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?
@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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With