You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React跳转/courses路由未加载MongoDB全量课程数据问题求助

问题根因

  1. Redux 中存储的课程列表数据在执行搜索后被覆盖为搜索结果,跳转回 /courses 路径时,没有触发重新拉取全量课程的逻辑。
  2. App 组件中拉取全量课程的 useEffect 仅在 App 首次挂载时执行一次,路由跳转时 App 不会重新挂载,因此不会重新请求全量数据。
  3. /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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 22:54:03