Introduction to React for Django Developers
# React for Django Developers
As a Django developer, adding React to your toolkit opens up powerful frontend possibilities. Here's how to get started.
## Why React + Django?
- **Best of both worlds**: Django's robust backend + React's dynamic frontend
- **API-first approach**: Build once, use anywhere
- **Scalability**: Separate concerns for better maintainability
- **Performance**: Virtual DOM for efficient updates
## Architecture Options
### 1. Monolithic (Django serves React)
```
myproject/
├── backend/ # Django app
│ ├── api/
│ └── templates/
└── frontend/ # React app
├── src/
└── build/ # Served by Django
```
**Pros:** Simple deployment, shared session
**Cons:** Coupled, harder to scale independently
### 2. Decoupled (Separate deployments)
```
Backend: api.example.com (Django)
Frontend: app.example.com (React on CDN)
```
**Pros:** Independent scaling, separate teams
**Cons:** CORS handling, separate deployments
## Setting Up React
```bash
# Create React app
npx create-react-app frontend
cd frontend
npm start
```
## Connecting to Django API
Install axios for API calls:
```bash
npm install axios
```
Create an API service:
```javascript
// src/services/api.js
import axios from 'axios';
const API_BASE = process.env.REACT_APP_API_URL || 'http://localhost:8000/api';
const api = axios.create({
baseURL: API_BASE,
headers: {
'Content-Type': 'application/json',
},
});
// Add auth token to requests
api.interceptors.request.use((config) => {
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Token ${token}`;
}
return config;
});
export default api;
```
## Fetching Data
```javascript
// src/components/ProductList.jsx
import { useState, useEffect } from 'react';
import api from '../services/api';
function ProductList() {
const [products, setProducts] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchProducts = async () => {
try {
const response = await api.get('/products/');
setProducts(response.data);
} catch (error) {
console.error('Error fetching products:', error);
} finally {
setLoading(false);
}
};
fetchProducts();
}, []);
if (loading) return <div>Loading...</div>;
return (
<div className="grid grid-cols-3 gap-4">
{products.map((product) => (
<div key={product.id} className="border p-4 rounded">
<h3>{product.name}</h3>
<p>${product.price}</p>
</div>
))}
</div>
);
}
export default ProductList;
```
## Django CORS Setup
Allow React to call your API:
```python
# settings.py
INSTALLED_APPS = [
...
'corsheaders',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
...
]
CORS_ALLOWED_ORIGINS = [
'http://localhost:3000',
]
# For development only:
# CORS_ALLOW_ALL_ORIGINS = True
```
## Authentication Flow
### Login Component
```javascript
// src/components/Login.jsx
import { useState } from 'react';
import api from '../services/api';
function Login({ onLogin }) {
const [credentials, setCredentials] = useState({
username: '',
password: '',
});
const handleSubmit = async (e) => {
e.preventDefault();
try {
const response = await api.post('/auth/login/', credentials);
localStorage.setItem('token', response.data.token);
onLogin(response.data.user);
} catch (error) {
alert('Login failed');
}
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={credentials.username}
onChange={(e) => setCredentials({...credentials, username: e.target.value})}
placeholder="Username"
/>
<input
type="password"
value={credentials.password}
onChange={(e) => setCredentials({...credentials, password: e.target.value})}
placeholder="Password"
/>
<button type="submit">Login</button>
</form>
);
}
```
## State Management
For larger apps, consider:
- **React Context**: Built-in, good for simple state
- **Redux Toolkit**: Industry standard, powerful DevTools
- **Zustand**: Minimal, modern alternative
- **React Query**: For server state management
## Deployment
### Build React for Production
```bash
npm run build
```
### Serve with Django
```python
# settings.py
STATICFILES_DIRS = [
BASE_DIR / 'frontend' / 'build' / 'static',
]
# urls.py
from django.views.generic import TemplateView
urlpatterns = [
...
path('', TemplateView.as_view(template_name='index.html')),
]
```
## Best Practices
1. **Use environment variables** for API URLs
2. **Handle loading states** in all components
3. **Implement proper error handling**
4. **Use TypeScript** for larger projects
5. **Test components** with React Testing Library
## Next Steps
- Learn React Router for navigation
- Explore React Query for data fetching
- Add Tailwind CSS for styling
- Implement WebSockets for real-time updates
Check out our React + Django templates in the marketplace!