I want to add just React ponents to Django's template html file (not replace entire template with React as Frontend that there are a lot of tutorial on internet, just certain part of website) because that part of website require high interactivity which is easier to write it in React.
I followed Add React to a Website tutorial to add JSX preprocessor. I set up project like this.
/app-a
/static
/app-a <-- preprocessed files are here
/templates
/app-a
index.html <-- Django template file that I want to include a react ponent to
/app-b
/react <-- this is where I wrote JSX files
manage.py
package.json
And included React files at the end of index.html file like this.
<html>
<body>
<div id="formContainer">
</div>
<!-- React -->
<script src="@16/umd/react.development.js" crossorigin></script>
<script src="@16/umd/react-dom.development.js" crossorigin></script>
<!-- my root React ponent file -->
<script src="{% static 'app-a/App.js' %}"></script>
</body>
And I ran babel --watch
to preprocess JSX files like this
npx babel --watch ./react --out-dir ./app-a/static/app-a --presets react-app
I thought it worked because whenever I saved JSX ponent files, they were preprocessed and output to /app-a/static/app-a
.
At the end of root JSX file, I included root React ponent to DOM like this.
import React, { Component } from 'react';
... import bunch of ponents
class App extends Component { ... }
const formContainer = document.querySelector('#formContainer');
ReactDOM.render(App, formContainer);
Unfortunately, when I open website, I get error Uncaught SyntaxError: Unexpected identifier
at import React, { Component } from 'react';
from preprocessed root React ponent file.
If I delete React
from import statement (directly in preprocessed file), I get error Uncaught SyntaxError: Unexpected token {
and If I delete the first import line, I get the same Unexpected identifier error at next import line.
So, I think web browser have a problem with import
statement.
I thought babel should take care of converting everything in JSX files to JS files that are able to run on web browser.
I'm sure that my JSX files are correct because I wrote these ponents in Create React App project before I copied all of JSX files to django project.
So, what should I do to add a React ponent to my website?
I want to add just React ponents to Django's template html file (not replace entire template with React as Frontend that there are a lot of tutorial on internet, just certain part of website) because that part of website require high interactivity which is easier to write it in React.
I followed Add React to a Website tutorial to add JSX preprocessor. I set up project like this.
/app-a
/static
/app-a <-- preprocessed files are here
/templates
/app-a
index.html <-- Django template file that I want to include a react ponent to
/app-b
/react <-- this is where I wrote JSX files
manage.py
package.json
And included React files at the end of index.html file like this.
<html>
<body>
<div id="formContainer">
</div>
<!-- React -->
<script src="https://unpkg./react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg./react-dom@16/umd/react-dom.development.js" crossorigin></script>
<!-- my root React ponent file -->
<script src="{% static 'app-a/App.js' %}"></script>
</body>
And I ran babel --watch
to preprocess JSX files like this
npx babel --watch ./react --out-dir ./app-a/static/app-a --presets react-app
I thought it worked because whenever I saved JSX ponent files, they were preprocessed and output to /app-a/static/app-a
.
At the end of root JSX file, I included root React ponent to DOM like this.
import React, { Component } from 'react';
... import bunch of ponents
class App extends Component { ... }
const formContainer = document.querySelector('#formContainer');
ReactDOM.render(App, formContainer);
Unfortunately, when I open website, I get error Uncaught SyntaxError: Unexpected identifier
at import React, { Component } from 'react';
from preprocessed root React ponent file.
If I delete React
from import statement (directly in preprocessed file), I get error Uncaught SyntaxError: Unexpected token {
and If I delete the first import line, I get the same Unexpected identifier error at next import line.
So, I think web browser have a problem with import
statement.
I thought babel should take care of converting everything in JSX files to JS files that are able to run on web browser.
I'm sure that my JSX files are correct because I wrote these ponents in Create React App project before I copied all of JSX files to django project.
So, what should I do to add a React ponent to my website?
- 1 Babel transpiles ES6 to ES5 syntax, but to resolve imports you need a bundler like webpack – SrThompson Commented Jul 21, 2018 at 6:39
- medium./uva-mobile-devhub/… This might be of some help. – Vaibhav Vishal Commented Oct 12, 2018 at 9:07
1 Answer
Reset to default 9I've had to deal with this exact problem. I just needed to add a react ponent to a page and nothing else. Most tutorials online remend decoupling React and Django, which wasn't feasible for the project I was working on. An easier way seems to involve creating a new app to contain the react ponents and adding this to the INSTALLED_APPS
in your project's settings.py
so the static files generated by webpack are discovered by django.
Setup yarn or npm and install a few dependencies and dev-depedencies that are required for transpiling the code. You can use your bundler of choice, I'm using webpack since it's the most popular:
cd react_ponent (or wherever your new project is)
yarn init -y
yarn add -D @babel/core @babel/preset-env @babel/preset-react babel-loader webpack webpack-cli
yarn add react react-dom
Create a webpack.config.js
in your app directory with the following contents:
const path = require('path');
module.exports = {
entry: path.resolve(__dirname, 'static_src', 'index.js'),
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
],
},
output: {
path: path.resolve(__dirname, 'static', 'react_ponent'),
filename: 'bundle.js',
},
resolve: {
extensions: ['*', '.js', '.jsx'],
},
};
And a .babelrc
in the same directory:
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}
Create a static_src
directory to store your JavaScript files, and a static
directory for the bundled files webpack generates.
Create static_src/index.js
and render your root ponent:
import React from 'react';
import ReactDOM from 'react-dom';
import Component from "./Component";
ReactDOM.render(<Component/>, document.getElementById('ponent-root'));
and you should be good to go. Run npx webpack
in the react_ponent/
directory to transpile your files and generate a bundle.js
which you can include anywhere in your project like so:
{% load static %}
<div id="ponent-root"></div>
<script src="{% static 'react_ponent/bundle.js' %}"></script>