如何用React.js实现搜索结果在独立页面展示?
MERN栈实现搜索关键词并展示结果方案
核心实现思路
- 前端:做搜索输入组件收集关键词,通过路由跳转把关键词传到结果页面;结果页面拿到关键词后,调用后端接口获取匹配数据再渲染出来。
- 后端:写API接口接收前端传的关键词,用MongoDB正则查询匹配数据库数据,返回给前端。
- 路由:借助
react-router-dom实现页面跳转和参数传递。
代码示例
1. 前端(React)部分
搜索组件(SearchBar.jsx)
import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; const SearchBar = () => { const [keyword, setKeyword] = useState(''); const navigate = useNavigate(); const handleSearch = (e) => { e.preventDefault(); if (keyword.trim()) { // 跳转到结果页面并携带关键词参数 navigate(`/search-results?keyword=${encodeURIComponent(keyword)}`); setKeyword(''); } }; return ( <form onSubmit={handleSearch} style={{ margin: '20px' }}> <input type="text" value={keyword} onChange={(e) => setKeyword(e.target.value)} placeholder="输入关键词搜索..." style={{ padding: '8px', width: '300px' }} /> <button type="submit" style={{ padding: '8px 16px', marginLeft: '8px' }}> 搜索 </button> </form> ); }; export default SearchBar;
搜索结果页面(SearchResults.jsx)
import { useState, useEffect } from 'react'; import { useLocation } from 'react-router-dom'; const SearchResults = () => { const [results, setResults] = useState([]); const [loading, setLoading] = useState(true); const location = useLocation(); useEffect(() => { // 从URL参数中提取关键词 const searchParams = new URLSearchParams(location.search); const keyword = searchParams.get('keyword'); if (keyword) { fetch(`http://localhost:5000/api/search?keyword=${encodeURIComponent(keyword)}`) .then(res => res.json()) .then(data => { setResults(data); setLoading(false); }) .catch(err => { console.error('搜索请求失败:', err); setLoading(false); }); } }, [location.search]); if (loading) { return <div style={{ padding: '20px' }}>加载中...</div>; } return ( <div style={{ padding: '20px' }}> <h2>搜索结果</h2> {results.length === 0 ? ( <p>没有找到匹配的内容</p> ) : ( <ul> {results.map(item => ( <li key={item._id} style={{ margin: '10px 0' }}> <h3>{item.title}</h3> <p>{item.description}</p> </li> ))} </ul> )} </div> ); }; export default SearchResults;
路由配置(App.jsx)
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import SearchBar from './SearchBar'; import SearchResults from './SearchResults'; import Home from './Home'; // 替换成你的首页组件 function App() { return ( <Router> <SearchBar /> <Routes> <Route path="/" element={<Home />} /> <Route path="/search-results" element={<SearchResults />} /> </Routes> </Router> ); } export default App;
2. 后端(Node.js + Express + MongoDB)部分
数据模型(models/Item.js)
const mongoose = require('mongoose'); const itemSchema = new mongoose.Schema({ title: { type: String, required: true }, description: { type: String, required: true }, // 根据需求添加其他字段 }); module.exports = mongoose.model('Item', itemSchema);
搜索API路由(routes/search.js)
const express = require('express'); const router = express.Router(); const Item = require('../models/Item'); router.get('/', async (req, res) => { try { const keyword = req.query.keyword; // 用正则查询匹配标题或描述,忽略大小写 const items = await Item.find({ $or: [ { title: { $regex: keyword, $options: 'i' } }, { description: { $regex: keyword, $options: 'i' } } ] }); res.json(items); } catch (err) { res.status(500).json({ message: err.message }); } }); module.exports = router;
服务器入口文件(server.js)
const express = require('express'); const mongoose = require('mongoose'); const cors = require('cors'); const searchRoutes = require('./routes/search'); const app = express(); const PORT = 5000; // 中间件配置 app.use(cors()); app.use(express.json()); // 连接MongoDB mongoose.connect('mongodb://localhost:27017/your-db-name', { useNewUrlParser: true, useUnifiedTopology: true }) .then(() => console.log('MongoDB连接成功')) .catch(err => console.error('MongoDB连接失败:', err)); // 挂载搜索路由 app.use('/api/search', searchRoutes); app.listen(PORT, () => { console.log(`服务器运行在端口 ${PORT}`); });
注意事项
- 确保MongoDB服务已启动,server.js中的数据库名称要和实际一致。
- 前端请求地址要和后端运行地址匹配,生产环境需替换为实际域名。
- 可以根据需求扩展搜索字段,比如添加标签、分类等查询条件。
- 建议给搜索输入加防抖,避免用户输入时频繁触发后端请求。
内容的提问来源于stack exchange,提问作者Manik Islam Mahi
相关产品推荐
相关产品推荐

