- Now that we have some endpoints setup on our backend we can begin to setup a way for our front end to get our data, which for now is just a placeholder message.
- Make sure our server is still running, and enter your client folder and start up our react application in a new terminal. You can create a new terminal tab or you can split your current terminal. Here is how it should look if you split your terminal, to start up the react app run
npm start

- We will use the JavaScript fetch API to communicate from our React app to the backend. See the updated App.jsx file below.
import { useEffect } from "react";
export default function App() {
useEffect(() => {
const getTodos = async () => {
const res = await fetch("<http://localhost:5000/api/todos>");
const todos = await res.json();
console.log(todos);
};
getTodos();
}, [])
return (
<main className="container">
<h1>Awesome Todos</h1>
</main>
);
}
- Here we are using the useEffect hook provided by react with an empty dependency array to run the async getTodos function once our component is mounted.
- Our endpoint will return a readable stream so we will have to use the .json() method to get the data from our backend.
- However, if we open up our browser and check out console we will see a few errors, the one I want to point out is
Access to fetch at 'http://localhost:5000/api/todos' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource…
- In other words, we are not allowed to communicate with our backend due to them being on different ports. There are several ways to deal with this issue but for our current case we will use a proxy during our development.
- Go into the package.json file (in your client) and add a proxy value
{
"name": "client",
"version": "0.1.0",
"private": true,
"proxy": "<http://localhost:5000>",
"dependencies": {
//...
}
- Now we will have to restart our React application, close it down and re-run
npm start
- Update the App.jsx file to reflect this proxy
import { useEffect } from "react";
export default function App() {
useEffect(() => {
const getTodos = async () => {
const res = await fetch("/api/todos");
const todos = await res.json();
console.log(todos);
};
getTodos();
}, [])
return (
<main className="container">
<h1>Awesome Todos</h1>
</main>
);
}
- Since we are now using a proxy we can call “/api/todos” directly and our React app will first check if that endpoint exists on http://localhost:3000 and if not it will then check our proxy http://localhost:5000 (our backend server)
- If we open our browser and check our console we should see the following

- create-react-app sets up our application in StrictMode, this is the reason why our console is logging the message twice, this will not be the case once we are in production so no need to worry about this.
- We can take an extra step here an let us display our message onto our webpage, update the App.jsx to reflect the following