Node Express Part3
by Kuligaposten 2026-02-16
A guide in Node Express backend.
Part 3: Connecting Express + MongoDB API to a React Frontend
By the end of this guide, you’ll have a React app that can create, read, update, and delete users via the Express API you built in Part 2.
1. Prerequisites
- Node.js + npm (or yarn)
- Your Express + MongoDB API running locally (
npm run dev) - Basic React knowledge (optional, but helpful)
2. Create a React App
Use Vite or Create React App. I’ll use Vite for speed:
npm create vite@latest my-react-app
# Choose React + JavaScript
cd my-react-app
npm install
npm run dev
Your React app will now be running at http://localhost:5173 (or similar).
3. Install Axios
We’ll use Axios to make HTTP requests:
npm install axios
4. Create a Service for API Calls
In src/services/api.js:
import axios from "axios";
const API_URL = "http://localhost:3000/api/users";
export const getUsers = () => axios.get(API_URL);
export const getUser = (id) => axios.get(`${API_URL}/${id}`);
export const createUser = (data) => axios.post(API_URL, data);
export const updateUser = (id, data) => axios.put(`${API_URL}/${id}`, data);
export const deleteUser = (id) => axios.delete(`${API_URL}/${id}`);
5. Build a Simple Users Component
Create src/components/Users.jsx:
import React, { useState, useEffect } from "react";
import { getUsers, createUser, updateUser, deleteUser } from "../services/api";
export default function Users() {
const [users, setUsers] = useState([]);
const [name, setName] = useState("");
const [email, setEmail] = useState("");
// Fetch users on load
useEffect(() => {
fetchUsers();
}, []);
const fetchUsers = async () => {
try {
const response = await getUsers();
setUsers(response.data);
} catch (err) {
console.error(err);
}
};
const handleAddUser = async () => {
if (!name || !email) return;
try {
await createUser({ name, email });
setName("");
setEmail("");
fetchUsers();
} catch (err) {
console.error(err);
}
};
const handleDeleteUser = async (id) => {
try {
await deleteUser(id);
fetchUsers();
} catch (err) {
console.error(err);
}
};
return (
<div>
<h2>Users</h2>
<div>
<input
placeholder="Name"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<input
placeholder="Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<button onClick={handleAddUser}>Add User</button>
</div>
<ul>
{users.map((user) => (
<li key={user._id}>
{user.name} ({user.email})
<button onClick={() => handleDeleteUser(user._id)}>Delete</button>
</li>
))}
</ul>
</div>
);
}
6. Render Users Component in App
Update src/App.jsx:
import React from "react";
import Users from "./components/Users";
function App() {
return (
<div className="App">
<h1>My Full-Stack App</h1>
<Users />
</div>
);
}
export default App;
7. CORS Setup
Since React runs on a different port than Express, enable CORS in your API:
npm install cors
In index.js of your Express app:
const cors = require("cors");
app.use(cors());
Now your React frontend can make requests to your API without issues.
8. Optional: Edit Users
You can expand your app with an edit feature. For example, add handleEditUser in the Users.jsx component:
const handleEditUser = async (id) => {
const newName = prompt("Enter new name:");
const newEmail = prompt("Enter new email:");
if (!newName || !newEmail) return;
try {
await updateUser(id, { name: newName, email: newEmail });
fetchUsers();
} catch (err) {
console.error(err);
}
};
And add a button:
<button onClick={() => handleEditUser(user._id)}>Edit</button>
9. Final Structure
Your project structure may look like:
my-react-app/
│
├── src/
│ ├── components/
│ │ └── Users.jsx
│ ├── services/
│ │ └── api.js
│ └── App.jsx
├── package.json
└── vite.config.js
Conclusion
You now have a full-stack application:
- Backend: Node.js + Express + MongoDB API
- Frontend: React app with CRUD functionality
- Communication: Axios requests over HTTP with CORS enabled
From here, you can:
- Add better styling (Tailwind, Material UI, etc.)
- Implement authentication (JWT or OAuth)
- Deploy your app to Vercel/Netlify (frontend) and Render/Heroku (backend)