如何在React/Next.js中实现从服务器/MySQL动态获取数据?
在Next.js中从MySQL数据库动态获取数据替代静态数据
一、准备工作:安装依赖
首先安装MySQL数据库驱动,比如mysql2:
npm install mysql2 # 或使用yarn yarn add mysql2
二、创建数据库连接文件
在项目根目录下新建lib/db.js,统一管理数据库连接逻辑:
import mysql from 'mysql2/promise'; export async function connectToDB() { const connection = await mysql.createConnection({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME }); return connection; }
注意:数据库配置不要硬编码,放到项目根目录的.env.local文件中:
DB_HOST=localhost DB_USER=root DB_PASSWORD=你的数据库密码 DB_NAME=你的数据库名称
三、编写API路由(用于客户端动态请求)
如果需要在客户端交互时获取数据,在pages/api/books.js创建API路由:
import { connectToDB } from '../../lib/db'; export default async function handler(req, res) { if (req.method !== 'GET') { return res.status(405).json({ message: '仅支持GET请求' }); } try { const connection = await connectToDB(); const [rows] = await connection.execute('SELECT id, title FROM books'); await connection.end(); res.status(200).json(rows); } catch (error) { res.status(500).json({ message: '获取数据失败', error: error.message }); } }
四、在页面中实现动态数据获取
根据业务场景选择以下任意一种方式:
方式1:服务器端渲染(SSR)- 实时获取最新数据
适合需要每次请求都拿到最新数据的页面,使用getServerSideProps:
// pages/books.js import { connectToDB } from '../lib/db'; export default function BooksPage({ books }) { return ( <div> <h1>书籍列表</h1> <ul> {books.map(book => ( <li key={book.id}>{book.title}</li> ))} </ul> </div> ); } export async function getServerSideProps() { try { const connection = await connectToDB(); const [rows] = await connection.execute('SELECT id, title FROM books'); await connection.end(); return { props: { books: rows } }; } catch (error) { return { props: { books: [] } }; } }
方式2:静态生成+增量再生(ISR)- 兼顾性能与 freshness
适合数据不需要实时更新,但需要定期刷新的场景,使用getStaticProps加revalidate:
// pages/books.js import { connectToDB } from '../lib/db'; export default function BooksPage({ books }) { return ( <div> <h1>书籍列表</h1> <ul> {books.map(book => ( <li key={book.id}>{book.title}</li> ))} </ul> </div> ); } export async function getStaticProps() { try { const connection = await connectToDB(); const [rows] = await connection.execute('SELECT id, title FROM books'); await connection.end(); return { props: { books: rows }, revalidate: 60 // 每60秒自动重新生成页面 }; } catch (error) { return { props: { books: [] } }; } }
方式3:客户端请求(CSR)- 交互时动态获取
适合需要在用户操作后加载数据的场景,使用fetch:
// pages/books.js import { useState, useEffect } from 'react'; export default function BooksPage() { const [books, setBooks] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { async function fetchBooks() { try { const res = await fetch('/api/books'); if (!res.ok) throw new Error('请求失败'); const data = await res.json(); setBooks(data); } catch (err) { setError(err.message); } finally { setLoading(false); } } fetchBooks(); }, []); if (loading) return <div>加载中...</div>; if (error) return <div>错误:{error}</div>; return ( <div> <h1>书籍列表</h1> <ul> {books.map(book => ( <li key={book.id}>{book.title}</li> ))} </ul> </div> ); }
五、替换原有静态数据导入
删除代码中原来的import { books } from './comments.js'语句,改用上述动态获取方式即可。
内容的提问来源于stack exchange,提问作者user20885204
相关产品推荐
相关产品推荐

