Published on September 30, 2024By DeveloperBreeze

How to Build a Fullstack App with Flask and React

In this tutorial, we'll walk you through creating a simple fullstack application using Flask (for the backend) and React (for the frontend). By the end of this guide, you'll be able to build a basic Task Manager where users can create, read, update, and delete tasks, with data flowing seamlessly between Flask and React.

Table of Contents

  1. Introduction
  2. Setting Up the Project
  3. Building the Backend with Flask
  4. Building the Frontend with React
  5. Connecting Flask and React
  6. Adding API Endpoints in Flask
  7. Handling Data in React with Axios
  8. Form Handling and CRUD Operations
  9. Deploying the Application
  10. Conclusion

1. Introduction

The Task Manager app will use Flask as the backend to manage the API and data, and React as the frontend to handle user interactions and display. Our app will cover:

  • Building the Flask backend to manage tasks (API).
  • Building the React frontend to display and manipulate tasks.
  • Connecting Flask and React to work seamlessly together.

2. Setting Up the Project

Step 1: Create the Project Folder

Begin by setting up a directory for your fullstack app:

mkdir flask-react-task-manager
cd flask-react-task-manager

Step 2: Set up a Python Virtual Environment

To isolate dependencies, create a Python virtual environment:

python3 -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

Step 3: Install Flask

Next, install Flask in your virtual environment:

pip install Flask

Step 4: Set up the React Frontend

Use create-react-app to set up the React frontend:

npx create-react-app frontend
cd frontend
npm start  # Starts the React development server

The basic project structure should look like this:

flask-react-task-manager/
    ├── venv/
    ├── app.py  # Flask backend
    └── frontend/  # React frontend

3. Building the Backend with Flask

Now, let's set up a simple Flask app to serve the backend API.

Step 1: Create the Flask App

In the project root, create a file called app.py:

from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/')
def index():
    return jsonify({"message": "Welcome to the Task Manager API!"})

if __name__ == '__main__':
    app.run(debug=True)

Step 2: Run the Flask App

To run your Flask app, execute:

python app.py

Visit http://127.0.0.1:5000/ in your browser. You should see:

{"message": "Welcome to the Task Manager API!"}

4. Building the Frontend with React

Now that the backend is up, let's move to the React frontend.

Step 1: Modify the React Frontend

In the frontend/src/ directory, modify App.js to call the Flask API and display the message:

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

function App() {
  const [message, setMessage] = useState('');

  useEffect(() => {
    // Fetch data from the Flask API
    axios.get('http://127.0.0.1:5000/')
      .then(response => setMessage(response.data.message))
      .catch(error => console.log(error));
  }, []);

  return (
    <div className="App">
      <h1>{message}</h1>
    </div>
  );
}

export default App;

Step 2: Install Axios

To fetch data from the Flask backend, install Axios in the React frontend:

npm install axios

Run npm start inside the frontend directory again. The React app should now display the message from the Flask API.


5. Connecting Flask and React

Step 1: Enable CORS in Flask

To allow the React frontend to communicate with Flask, we need to enable CORS. Install the Flask-CORS package:

pip install flask-cors

Now, modify app.py to enable CORS:

from flask_cors import CORS

app = Flask(__name__)
CORS(app)

This will allow the frontend (running on a different port) to make requests to the backend.


6. Adding API Endpoints in Flask

Next, let’s add API endpoints in Flask to handle tasks.

Step 1: Create Task Data

In app.py, add a sample data structure for tasks:

tasks = [
    {"id": 1, "title": "Task 1", "description": "This is task 1", "done": False},
    {"id": 2, "title": "Task 2", "description": "This is task 2", "done": True},
]

Step 2: Add API Routes

Now, add routes to retrieve, create, and delete tasks:

from flask import request

@app.route('/tasks', methods=['GET'])
def get_tasks():
    return jsonify(tasks)

@app.route('/tasks', methods=['POST'])
def create_task():
    new_task = request.json
    new_task['id'] = len(tasks) + 1
    tasks.append(new_task)
    return jsonify(new_task), 201

@app.route('/tasks/<int:id>', methods=['DELETE'])
def delete_task(id):
    task = next((task for task in tasks if task['id'] == id), None)
    if task:
        tasks.remove(task)
        return jsonify({"message": "Task deleted"}), 200
    return jsonify({"message": "Task not found"}), 404

These routes allow us to create, retrieve, and delete tasks.


7. Handling Data in React with Axios

Let’s now connect the API endpoints with the React frontend.

Step 1: Fetch Tasks in React

Update App.js to fetch tasks from the backend:

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

function App() {
  const [tasks, setTasks] = useState([]);

  useEffect(() => {
    axios.get('http://127.0.0.1:5000/tasks')
      .then(response => setTasks(response.data))
      .catch(error => console.log(error));
  }, []);

  return (
    <div className="App">
      <h1>Task List</h1>
      <ul>
        {tasks.map(task => (
          <li key={task.id}>{task.title}</li>
        ))}
      </ul>
    </div>
  );
}

export default App;

Step 2: Create Tasks in React

Add a simple form to create new tasks. Create a new component TaskForm.js:

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

function TaskForm({ onTaskCreated }) {
  const [title, setTitle] = useState('');
  const [description, setDescription] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault();
    axios.post('http://127.0.0.1:5000/tasks', { title, description, done: false })
      .then(response => {
        onTaskCreated(response.data);
        setTitle('');
        setDescription('');
      })
      .catch(error => console.log(error));
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>Title</label>
        <input type="text" value={title} onChange={e => setTitle(e.target.value)} />
      </div>
      <div>
        <label>Description</label>
        <input type="text" value={description} onChange={e => setDescription(e.target.value)} />
      </div>
      <button type="submit">Add Task</button>
    </form>
  );
}

export default TaskForm;

Now, update the main App.js file to handle new task creation:

import React, { useState, useEffect } from 'react';
import axios from 'axios';
import TaskForm from './TaskForm';

function App() {
  const [tasks, setTasks] = useState([]);

  useEffect(() => {
    axios.get('http://127.0.0.1:5000/tasks')
      .then(response => setTasks(response.data))
      .catch(error => console.log(error));
  }, []);

  const handleTaskCreated = (newTask) => {
    setTasks([...tasks, newTask]);
  };

  return (
    <div className="App">
      <h1>Task List</h1>
      <ul>
        {tasks.map(task => (
          <li key={task.id}>{task.title}</li>
        ))}
      </ul>
      <TaskForm onTaskCreated={handleTaskCreated} />
    </div>
  );
}

export default App;

8. Form Handling and CRUD Operations

We now have the following functionality:

  • Fetch tasks from Flask and display them in React.
  • Create new tasks using a form in React.

You can add more CRUD operations like Update and **

Delete** to complete the Task Manager app.

Step 1: Delete Task from React

To delete tasks, update App.js with a delete button for each task:

const deleteTask = (id) => {
  axios.delete(`http://127.0.0.1:5000/tasks/${id}`)
    .then(() => {
      setTasks(tasks.filter(task => task.id !== id));
    })
    .catch(error => console.log(error));
};

Update the task list to include the delete button:

<ul>
  {tasks.map(task => (
    <li key={task.id}>
      {task.title}
      <button onClick={() => deleteTask(task.id)}>Delete</button>
    </li>
  ))}
</ul>

9. Deploying the Application

Step 1: Build the React App

To prepare the React app for production, run:

npm run build

This will create a build/ directory with optimized files.

Step 2: Serve the React App with Flask

Move the build folder into your Flask project and modify app.py to serve the frontend:

from flask import send_from_directory

@app.route('/')
def serve_react_app():
    return send_from_directory('frontend/build', 'index.html')

@app.route('/<path:path>')
def serve_static_files(path):
    return send_from_directory('frontend/build', path)

Run Flask, and your app should now serve the React frontend alongside the API.


10. Conclusion

You now have a fully functioning fullstack app with Flask and React! You’ve learned to:

  • Set up Flask as a backend server.
  • Create RESTful API endpoints in Flask.
  • Fetch and display data in React.
  • Handle form submissions and CRUD operations in React.

This structure can be scaled and modified to fit more complex requirements, such as user authentication, database integration, and more.

Comments

Please log in to leave a comment.

Continue Reading:

Creating a Simple REST API with Flask

Published on August 03, 2024

python

Python Code Snippet: Simple RESTful API with FastAPI

Published on August 04, 2024

jsonpython

Building a Modern Web Application with React and Redux

Published on August 05, 2024

javascript

Weather App with Node.js

Published on August 08, 2024

javascript

React Custom Hook for API Requests

Published on August 12, 2024

javascript