I’m building a small full-stack project using Next.js (frontend) and Express.js (backend) with a MySQL database.
The Express backend has this route:
// server.js
import express from "express";
import mysql from "mysql2";
const app = express();
const db = mysql.createConnection({
host: "localhost",
user: "root",
password: "password",
database: "testdb"
});
app.get("/api/users", (req, res) => {
db.query("SELECT * FROM users", (err, results) => {
if (err) return res.status(500).json({ error: err.message });
res.json(results);
});
});
app.listen(5000, () => console.log("Server running on port 5000"));
When I open http://localhost:5000/api/users directly, it returns the list of users correctly.
But in my Next.js frontend, I try to fetch the same data:
// pages/index.js
import { useEffect, useState } from "react";
export default function Home() {
const [users, setUsers] = useState([]);
useEffect(() => {
fetch("http://localhost:5000/api/users")
.then((res) => res.json())
.then((data) => setUsers(data))
.catch((err) => console.error(err));
}, []);
return (
<div>
<h1>User List</h1>
<ul>
{users.map((u) => (
<li key={u.id}>{u.name}</li>
))}
</ul>
</div>
);
}
ut here, users is always undefined in the React component.
I already checked:
Express API works fine when called directly.
Next.js runs on port 3000.
There is no error in the browser console except:
TypeError: Cannot read properties of undefined (reading 'map')
usersisundefinedwhenmapis being called. Is this code exactly as written in your code? Make sure the initial state ofuseStateis an empty array.