React跳转/courses路由未加载MongoDB全量课程数据问题求助
问题根因
- Redux 中存储的课程列表数据在执行搜索后被覆盖为搜索结果,跳转回
/courses路径时,没有触发重新拉取全量课程的逻辑。 - App 组件中拉取全量课程的
useEffect仅在 App 首次挂载时执行一次,路由跳转时 App 不会重新挂载,因此不会重新请求全量数据。 /courses和/courses/search复用同一个Courses组件,跳转时组件不会重新挂载,默认不会触发数据更新。
修复方案
第一步:修改 Courses.js 组件
添加路由监听逻辑,根据当前路径自动拉取对应数据,同时兼容地址栏参数、清空搜索框状态:
import React, { useState, useEffect } from "react" import CourseHeader from "./CourseHeader" import CoursesList from "./CoursesList" import FilterCourse from "./FilterCourse" import Filtertech from "./Filtertech" import { useDispatch, useSelector } from "react-redux" // 新增导入useLocation import { useHistory, useLocation } from "react-router-dom" import { getCoursesBySearch, getCourses } from "../../actions/courses" const Courses = () => { const dispatch = useDispatch() const [search, setSearch] = useState("") const history = useHistory() // 新增获取当前路由信息 const location = useLocation() // 新增监听路由变化的useEffect useEffect(() => { const isSearchPath = location.pathname.startsWith('/courses/search') if (isSearchPath) { // 从地址栏取搜索参数,避免刷新页面参数丢失 const searchParams = new URLSearchParams(location.search) const searchQuery = searchParams.get('searchQuery') if (searchQuery && searchQuery !== 'none') { setSearch(searchQuery) dispatch(getCoursesBySearch({ search: searchQuery })) } } else { // 回到/courses根路径,拉取全量课程、清空搜索框 setSearch('') dispatch(getCourses()) } }, [location, dispatch]) const searchCourses = () => { if (search.trim()) { dispatch(getCoursesBySearch({ search })) history.push(`/courses/search?searchQuery=${search || "none"}`) } else { history.push("/courses") } } const handleKeyPress = (e) => { if (e.keyCode === 13) { searchCourses() } } const courses = useSelector((state) => state.courses) return ( <div className="row-start-2 row-end-3 col-start-1 col-end-2 mx-auto w-full max-w-5xl "> <div className="grid grid-cols-layout-course gap-x-3"> <div> <FilterCourse /> <Filtertech /> </div> <div> <CourseHeader handleKeyPress={handleKeyPress} setSearch={setSearch} search={search} /> <CoursesList courses={courses} /> </div> </div> </div> ) } export default Courses
第二步:可选优化 App.js 路由配置
可以将路由改为精确匹配,避免路径匹配异常,无需保留 App 中的全量课程拉取逻辑(已移到 Courses 组件中):
import "./App.css" import "./assets/output.css" import { BrowserRouter as Router, Switch, Route } from "react-router-dom" import Navbar from "./components/layouts/Navbar" import Courses from "./components/courses/Courses" import { useDispatch } from "react-redux" function App() { const dispatch = useDispatch() // 移除原有的useEffect拉取全量课程逻辑,避免重复请求 return ( <Router> <div className="App min-h-screen grid grid-rows-layout-desktop grid-cols-layout-desktop gap-10"> <Navbar /> <Switch> {/* 新增exact精确匹配根路径 */} <Route exact path="/courses"> <Courses /> </Route> <Route path="/courses/search"> <Courses /> </Route> </Switch> <Footer /> </div> </Router> ) } export default App
内容的提问来源于stack exchange,提问作者r121
相关产品推荐
相关产品推荐

