I have a simple application where I want to control a counter with React. I am trying to understand how data is sent from the frontend to the backend, and from the backend to the frontend.
I am able to POST the count to the backend, but I cannot return the count back to React. useEffect works for the POST request, but not the GET request and I'm not sure why.
I read this How to send data from React to Flask then back to react and show output on DOM, but I'm not familiar with enough React to understand class components yet.
app.py
from flask import Flask, request
app = Flask(__name__)
@app.route('/led', methods=['GET', 'POST'])
def led():
count = 1
if request.method == 'POST':
count = request.json['count']
return {'backendCount': count}
return {'backendCount': count}
LED.js
import React, { useEffect, useState } from "react";
function LED() {
const [count, setCount] = useState(1)
const [backendData, setBackendData] = useState([{}]);
function increment() {
const newCount = count + 1;
setCount(newCount);
}
function decrement() {
const newCount = count - 1;
setCount(newCount);
}
useEffect(() => {
fetch('/led').then(
response => response.json()
).then(data => setBackendData(data))
}, []);
useEffect(() => {
fetch('/led', {
method: 'POST',
headers: { "Content-Type": "application/json" },
body: JSON.stringify({"count": count})
}).then(() => {
console.log("POST: " + count)
})
})
return (
<div className="container">
<h1>LED Controller</h1>
<p>Change the number of seconds between the LED turning on and off.</p>
<h3>{count}</h3>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
<h1>Increment from backend:</h1>
<h3>{backendData.backendCount}</h3>
</div>
);
}
export default LED;
I think your useState declaration might be wrong and should define a different variable type.
You should try this, as it appears that backend is an object, and not an array of object.
import React, { useEffect, useState } from "react";
function LED() {
const [count, setCount] = useState(1)
const [backendData, setBackendData] = useState({});
function increment() {
const newCount = count + 1;
setCount(newCount);
}
function decrement() {
const newCount = count - 1;
setCount(newCount);
}
useEffect(() => {
fetch('/led').then(
response => response.json()
).then(data => setBackendData(data))
}, {});
useEffect(() => {
fetch('/led', {
method: 'POST',
headers: { "Content-Type": "application/json" },
body: JSON.stringify({"count": count})
}).then(() => {
console.log("POST: " + count)
})
})
return (
<div className="container">
<h1>LED Controller</h1>
<p>Change the number of seconds between the LED turning on and off.</p>
<h3>{count}</h3>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
<h1>Increment from backend:</h1>
<h3>{backendData.backendCount}</h3>
</div>
);
}
export default LED;
I solved my question by using a button to POST the data to the backend and then GET to the frontend.
app.py
from flask import Flask, request
app = Flask(__name__)
class StoredData:
count = 1
def update_count(cls, num):
cls.count = num
data = StoredData()
@app.route('/led', methods=['GET', 'POST'])
def led():
if request.method == 'POST':
count = request.json['count']
data.update_count(count)
return {'backendCount': data.count}
return {'backendCount': data.count}
LED.js
import React, { useEffect, useState } from "react";
function LED() {
const [count, setCount] = useState(1)
const [backendData, setBackendData] = useState([{}]);
function increment() {
const newCount = count + 1;
setCount(newCount);
}
function decrement() {
const newCount = count - 1;
setCount(newCount);
}
function handleTransfer() {
fetch('/led', {
method: 'POST',
headers: { "Content-Type": "application/json" },
body: JSON.stringify({"count": count})
}).then(() => {
console.log("POST: " + count)
})
fetch('/led').then(
response => response.json()
).then(data => setBackendData(data))
}
return (
<div className="container">
<h1>LED Controller</h1>
<p>Change the number of seconds between the LED turning on and off.</p>
<h3>{count}</h3>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
<h1>Increment from backend:</h1>
<button onClick={handleTransfer}>Transfer Data</button>
<h3>{backendData.backendCount}</h3>
</div>
);
}
export default LED;