How to connect Flask to ReactJs
Tags: react, webdev, python, javascript
Published: 2021-12-14 08:41:26

Building web applications with the `Flask` framework and the inbuilt [jinja](https://palletsprojects.com/p/jinja/) template is cool but hooking your backend to a react frontend(which I believe we all love 😉) is much more interesting. In this tutorial, you are going to be taken through the easy steps you need to take to connect your `Flask` backend to a `React` frontend. 

##Prerequisite
1) Beginner level understanding of the flask framework. If you are new to `Flask` you can check out my article on how to set up your flask project and use it with the [jinja](https://palletsprojects.com/p/jinja/) template engine [here](https://dev.to/nagatodev/getting-started-with-flask-1kn1). 

2) Familiarity with the basics of `ReactJs`. You will be making use of the `useState` hook and also fetching data from API using `axios`.

Let's get started.

## Project directory
Create the project directory where your application will be stored and then navigate into it.
```javascript
mkdir project
```
```javascript
cd project
```
## React frontend setup
Create the frontend react application by running:
```javascript
npx create-react-app flask_react
```
Move into the `flask_react` directory
```javascript
cd flask_react
```
and then start the frontend application by running
```javascript
npm start
```
The default react application page should pop up in your browser; if it does not, copy and open the link below in your browser.
```javascript
http://localhost:3000
```
![react default](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mmpra1xpsht2bx1o7ls2.png)

## Flask backend setup
Create a new directory in your base directory
```javascript
mkdir backend
```
then navigate into it
```javascript
cd backend
```
If you have been following my `Building a web application with Flask` series you should know the next thing that needs to be created. Yes, a virtual environment. Did you happen to get that right? 😀

### Virtual environment
It is recommended to always create a virtual environment before you start your project. This helps you to separate the packages you use in this application from other applications; any change you make here won't affect the same package in another application on your system. To create a  virtual environment on your system; run this command:
```javascript
For mac/unix users: python3 -m venv env
For windows users: py -m venv env
```
After creating the environment, activate it by running :
```javascript
For mac/unix users: source env/bin/activate
For windows users: .\env\Scripts\activate
```
### Installing Flask
Now that you have your environment up and running, you can go ahead and install Flask
```javascript
pip install flask
```
The next thing is to register the script in an environment file.
```javascript
pip install python-dotenv
```
After successful installation, create the `.flaskenv` file in the `backend` directory created above.
```javascript
touch .flaskenv
```
Please note that the preceding `.` is very important. If you name your file just `flaskenv`, any environment variable you'll put in it won't be read.

Now put your environment variables in the `.flaskenv` file:
```javascript
FLASK_APP=base.py
FLASK_ENV=development
```
The application environment is set to development mode so you can easily debug your application and the base.py file which will contain your flask application will be created in the next section.

If the above approach is not used, you would need to keep on exporting your environment variables using `export FLASK_APP=base.py` and `export FLASK_ENV=development` whenever you restart your terminal window.

**Note:** To ensure that the focus of this article doesn't deviate, I'll be making the flask backend structure simple. If you want to build bigger projects you definitely have to create a better folder structure for your application. You can check out my articles on [Getting started with Flask](https://dev.to/nagatodev/getting-started-with-flask-1kn1) and [Building a Todo List Application with Flask](https://dev.to/nagatodev/building-a-todo-list-application-with-flask-fcj) if you need to learn how to create a folder structure for larger projects.

### base.py
Create a new file `base.py` in the `backend` directory where the `.flaskenv` directory is also located. 
```javascript
touch base.py
```
Your folder structure should currently look like 👇
![Folder structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nxushvw3xnha5k71ns1h.png)
Inside the `base.py` script create a simple API that returns your name and info about you:
```javascript
from flask import Flask

api = Flask(__name__)

@api.route('/profile')
def my_profile():
    response_body = {
        "name": "Nagato",
        "about" :"Hello! I'm a full stack developer that loves python and javascript"
    }

    return response_body
```
The code above contains a simple API which would be called by the react front end to get the `response_body` dictionary.

You might have noticed two things:
i) the `GET` http method is not specified here. This is because, by default, `view` functions in flask accept GET requests only.
ii) the `response_body` dictionary being returned at the end of the function is not being passed as an argument to the popular `jsonify` function like this `jsonify(response_body)`. This is because view functions in Flask can return a dictionary, which Flask then turns to JSON format.

The backend has been successfully set up, you can test this by running your application.
```javascript
flask run
```
Then navigate to the url `http://127.0.0.1:5000/profile`.You should see the dictionary `response_body` rendered in JSON format.

![flask-run-view](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e9xh5xpucwv4imfjfq6h.png)

You could also use `postman` to confirm this and you'll still get the same result.
![postman-api-call](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5jpcob7r7jot1qowyiio.png)

If you want to push your code to source control. Don't forget to add your `env` and `__pycache__` folders to the `gitignore` file in the base directory.

```javascript
backend/env
backend/__pycache__
```

## Connecting the API endpoint(/profile) to the react frontend
Now you can return to the base directory where the react frontend is located.
```javascript
cd ..
```
###Install the `axios` library:
**Note:** You can choose to use either `axios` or `fetch` to make HTTP requests. However, in this article, the `axios` library will be used to make requests to the API endpoints you built earlier on.
```javascript
npm install axios
```
###package.json
Open the package.json file and add the proxy below the "private": true, line so it ends up like 👇.
```javascript
  "name": "flask_react",
  "version": "0.1.0",
  "private": true,
  "proxy": "http://localhost:5000", //newline
```
By doing this, you will be able to use relative paths when you are making the API requests. Instead of making use of `http://localhost:5000/profile` you can simply make use of `/profile`.
 
**Note:** The default url which is normally used to access flask applications in the browser is `http://127.0.0.1:5000` but `http://localhost:5000` was used above as the value to the proxy key. Don't be confused, they are both the same. You can read more on that [here](https://whatismyipaddress.com/localhost)

Don't close the `package.json` file yet. There is something cool you can add as well. You know that whenever your react server is started and you make any change in a file and you save it, the server restarts so that the new change can reflect right?. You can also add that feature to your flask backend application. This is another advantage of connecting react to flask 😎.

Under the `scripts` section add another key and value. 
`"start-backend": "cd backend && env/bin/flask run --no-debugger",` so it ends up looking like 👇

```javascript
  "scripts": {
    "start": "react-scripts start",
    "start-backend": "cd backend && env/bin/flask run --no-debugger", //new line
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
```

Now you can start your backend server with `npm run start-backend`. This executes the command passed as its value in the package.json file. It navigates into the `env` directory in your `backend` directory and executes the `flask run` command.

The `--no-debugger` option is also passed here to disable the browser-based debugger as the Flask backend only serves as a server that holds the API endpoint.

###app.js
Here, you'll be making the call to the API endpoint in the flask backend server. After the changes, the app.js file will look exactly like 👇
 ```javascript 
import { useState } from 'react'
import axios from "axios";
import logo from './logo.svg';
import './App.css';

function App() {

   // new line start
  const [profileData, setProfileData] = useState(null)

  function getData() {
    axios({
      method: "GET",
      url:"/profile",
    })
    .then((response) => {
      const res =response.data
      setProfileData(({
        profile_name: res.name,
        about_me: res.about}))
    }).catch((error) => {
      if (error.response) {
        console.log(error.response)
        console.log(error.response.status)
        console.log(error.response.headers)
        }
    })}
    //end of new line 
    
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>

        {/* new line start*/}
        <p>To get your profile details: </p><button onClick={getData}>Click me</button>
        {profileData && <div>
              <p>Profile name: {profileData.profile_name}</p>
              <p>About me: {profileData.about_me}</p>
            </div>
        }
         {/* end of new line */}
      </header>
    </div>
  );
}

export default App;

``` 
Now let's go through the new lines of code added to the app.js file.

At the top of the file, the `useState` hook and axios module are both imported.

Then inside the function named `App` the useState hook is used to control the state of the `profileData` variable.

The `getData` function handles the API calls. It contains the `axios` module which is used to send a `GET` request to the API endpoint(\profile) on the backend which responds with the `jsonified` format of the dictionary declared in the view function. 

Next, the `setProfileData` function updates the state of `profileData` by assigning the data in the json response to `profile_name` and `about_me`.

The `getData` function is only called when the `click me` button is pressed.

Finally `&&` is used as a conditional operator, to avoid getting an error. `profileData` is going to be assigned an initial `null` state when the application first loads so if you try to access `profileData.profile_name` or `profileData.about_me` you get an error message. 
```javascript
TypeError: Cannot read properties of null (reading 'profile_name')
```
Hence the need for the `&&` conditional operator, so that the application only knows of the existence of the `profileData.profile_name` and `profileData.about_me` codes when the value of `profileData` has changed from `null` to containing the `response data` from the API call.

You don't need to make changes to any other file in the base directory. The work on the frontend part of the application is now complete. Now you can go ahead and test it:

Step1: start your backend server using `npm run start-backend`
**note** this command can be run while you are in any directory; be it the base directory(flask_react) or the flask directory (backend)

Step2: start your react server using `npm start`

![flask-react-project](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7doeymujo1m8zxgaftwa.png)

Now click on the `click me` button to make the API call and get the `name` and `about_me` data from the backend. 
![api call made to get name and about me data](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h08hsk3ael2synu0viwc.png)
 
Voila!! you have successfully connected your flask backend to your react frontend. Now I am sure you can build small API endpoints in your flask backend and call the endpoints from your react frontend.

If you have any questions, feel free to drop them as a comment or send me a message on [Linkedin](https://www.linkedin.com/in/faruq-abdulsalam) or [Twitter](https://twitter.com/Ace_II) and I'll ensure I respond as quickly as I can.

Incase you are a `Django` lover, you would definitely love to connect it to `React` as well. You can check out my article on [How to connect Django to ReactJs](https://dev.to/nagatodev/how-to-connect-django-to-reactjs-1a71) to learn how to go about that. Ciao 👋

![Cartman](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ais6tpi9rcyc91w64d86.gif)