This django library allows you to add React components into your django
templates.
Quick Setup
Make sure django_react_templatetags is added to your
INSTALLED_APPS.
INSTALLED_APPS = (
# ...
'django_react_templatetags',
)
You also need to add the react_context_processor into the
context_middleware:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
'templates...',
],
'APP_DIRS': True,
'OPTIONS': {
'debug': True,
'context_processors': [
...
'django_react_templatetags.context_processors.react_context_processor',
],
},
},
]
This should be enough to get started.
Simple example
This view…
from django.shortcuts import render
def menu_view(request):
return render(request, 'myapp/index.html', {
'menu_data': {
'example': 1,
},
})
… and this template:
{% load react %}
<html>
<head>...</head>
<body>
<nav>
{% react_render component="Menu" props=menu_data %}
</nav>
</body>
{% react_print %}
</html>
Will transform into this:
<html>
<head>...</head>
<body>
<nav>
<div id="Menu_405190d92bbc4d00b9e3376522982728"></div>
</nav>
</body>
<script>
ReactDOM.hydrate(
React.createElement(Menu, {"example": 1}),
document.getElementById('Menu_405190d92bbc4d00b9e3376522982728')
);
</script>
</html>
Working with models
In this example, by adding RepresentationMixin as a mixin to the
model, the templatetag will know how to generate the component data. You
only need to pass the model instance to the react_render
templatetag.
This model…
from django.db import models
from django_react_templatetags.mixins import RepresentationMixin
class Person(RepresentationMixin, models.Model):
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
def to_react_representation(self, context={}):
return {
'first_name': self.first_name,
'last_name': self.last_name,
}
…and this view
import myapp.models import Person
def person_view(request, pk):
return render(request, 'myapp/index.html', {
'menu_data': {
'person': Person.objects.get(pk=pk),
},
})
…and this template:
{% load react %}
<html>
<head>...</head>
<body>
<nav>
{% react_render component="Menu" props=menu_data %}
</nav>
</body>
{% react_print %}
</html>
…will transform into this:
...
<script>
ReactDOM.hydrate(
React.createElement(Menu, {"first_name": "Tom", "last_name": "Waits"}),
document.getElementById('Menu_405190d92bbc4d00b9e3376522982728')
);
</script>
Server Side Rendering
This library supports SSR (Server Side Rendering) throught third-part
library Hastur.
It works by posting component name and props to endpoint, that returns
the html rendition. Payload example:
{
"componentName": "MyComponent",
"props": {
"title": "my props title",
"anyProp": "another prop"
},
"static": false
}
REACT_RENDER_HOST needs to be defined to enable communication with
service.
FAQ
How do I override the markup generated by react_print?
Simple! Just override the template react_print.html
I dont like the autogenerated element id, can I supply my own?
Sure! Just add the param identifier="yourid" in react_render.
Example:
{% react_render component="Component" identifier="yourid" %}
…will print
<div id="yourid"></div>
How do I pass individual props?
Add your props as arguments prefixed with prop_* to your
{% react_render ... %}.
Example:
{% react_render component="Component" prop_country="Sweden" prop_city="Stockholm" %}
…will give the component this payload:
React.createElement(Component, {"country": "Sweden", "city": "Stockholm"}),
How do I apply my own css class to the autogenerated element?
Add class="yourclassname" to your {% react_render ... %}.
Example:
{% react_render component="Component" class="yourclassname" %}
…will print
<div id="Component_405190d92bbc4d00b9e3376522982728" class="yourclassname"></div>
I want to pass the component name as a variable, is that possible?
Yes! Just remove the string declaration and reference a variable in your
{% react_render ... %}, the same way you do with props.
Example:
This view
render(request, 'myapp/index.html', {
'component_name': 'MegaMenu',
})
…and this template
{% react_render component=component_name %}
…will print:
<div id="Component_405190d92bbc4d00b9e3376522982728" class="yourclassname"></div>
React.createElement(MegaMenu),