CodingBowl

Django REST Part 4 - Connecting React to Django: A Beginner's Guide

Published on 4 Jan 2026 Tech Development
image
Photo by Ante Hamersmit on Unsplash

You’ve built a secure Django API—now let’s use it. Learn how to build a React frontend that handles Token authentication and communicates with your 4 custom endpoints.

The Architecture: How they Talk

Because React and Django are two separate "islands," they communicate via HTTP requests. React sends a request (with a Token "key"), and Django sends back JSON data.

Step 1: The Django "CORS" Fix

By default, browsers block React (Port 3000) from talking to Django (Port 8000) for security. You must install django-cors-headers in your Django project:


# In your Django Terminal
pip install django-cors-headers

# In settings.py
INSTALLED_APPS = [..., 'corsheaders',]
MIDDLEWARE = ['corsheaders.middleware.CorsMiddleware', ...]
CORS_ALLOWED_ORIGINS = ["http://localhost:3000"]
        

Step 2: Initialize React & Bootstrap

Create your React app and install Axios (for API calls) and Bootstrap (for a clean UI):


npx create-react-app django-frontend
cd django-frontend
npm install axios bootstrap
        

Open src/index.js and add: import 'bootstrap/dist/css/bootstrap.min.css';

Step 3: The Critical Bootstrap Import

Installing Bootstrap isn't enough. You must tell React to load the CSS. Open src/main.jsx (Vite) or src/index.js (CRA) and add this line at the very top:

import 'bootstrap/dist/css/bootstrap.min.css';

Without this line, your buttons will look like plain blue links and your layout will be broken.

Step 4: The React "Controller" Code

Replace App.js with this logic. It maps exactly to the 4 URLs we built in previous posts:


import React, { useState } from 'react';
import axios from 'axios';

function App() {
  const [token, setToken] = useState('');
  const [response, setResponse] = useState(null);
  const API_URL = "http://127.0.0.1:8000/api";

  // Function to simplify headers
  const getHeaders = () => ({ headers: { Authorization: `Token ${token}` } });

  const handleAction = (method, endpoint, data = {}) => {
    const config = (endpoint === '/public/' || endpoint === '/login/') ? {} : getHeaders();
    
    axios({ method, url: `${API_URL}${endpoint}`, data, ...config })
      .then(res => {
        if(endpoint === '/login/') setToken(res.data.token);
        if(endpoint === '/logout/') setToken('');
        setResponse(res.data);
      })
      .catch(err => setResponse(err.response?.data || "Error Connecting"));
  };

  return (
    <div className="container py-5">
      <div className="card shadow border-0">
        <div className="card-header bg-dark text-white text-center">
          <h3>Django API Control Panel</h3>
        </div>
        <div className="card-body">
          <div className="btn-group w-100 mb-4">
            <button className="btn btn-outline-secondary" onClick={() => handleAction('get', '/public/')}>1. Public GET</button>
            <button className="btn btn-primary" onClick={() => handleAction('post', '/login/', {username:'admin', password:'123'})}>2. Login</button>
            <button className="btn btn-warning" onClick={() => handleAction('get', '/private/')}>3. Private GET</button>
            <button className="btn btn-danger" onClick={() => handleAction('post', '/logout/')}>4. Logout</button>
          </div>

          {response && (
            <div className="alert alert-light border">
              <strong>Server Response:</strong>
              <pre className="mt-2">{JSON.stringify(response, null, 2)}</pre>
            </div>
          )}
        </div>
        <div className="card-footer text-muted">
          Active Token: <code>{token || "No Session"}</code>
        </div>
      </div>
    </div>
  );
}
export default App;
        

State vs. Persistence: Managing Authentication Tokens in React

In React, useState acts as the app's "short-term memory," allowing the UI to react instantly when a token is received from Django. However, because state is stored in the computer's RAM, it is completely wiped clean the moment a user refreshes their browser. To solve this, we use localStorage, which acts as a "long-term vault" that saves the token to the browser's hard drive. By combining both, we can save the token to the disk upon login and automatically pull it back into the React state when the app restarts. This ensures a seamless user experience where the session remains active even after the tab is closed or the page is reloaded.

Final Troubleshooting Checklist

  • 403 Forbidden? Ensure you sent the header as Token [key] (with a space!).
  • Network Error? Make sure your Django server is actually running on port 8000.
  • CORS Error? Double-check the MIDDLEWARE order in Django; CorsMiddleware must be at the very top.

Meow! AI Assistance Note

This post was created with the assistance of Gemini AI and ChatGPT.
It is shared for informational purposes only and is not intended to mislead, cause harm, or misrepresent facts. While efforts have been made to ensure accuracy, readers are encouraged to verify information independently. Portions of the content may not be entirely original.

image
Photo by Yibo Wei on Unsplash