React如何用useEffect实现首页初始化时携带默认id运行请求函数
问题根源
- 路由配置逻辑错误:
<Switch>匹配到第一个符合条件的路由就会停止匹配,你定义了两个完全相同的path="/:id"路由,第二个DataById路由永远不会被触发,且你的需求是列表+详情同屏展示,不需要将详情组件单独配置为路由级组件。 - 首页路径
/下useParams()获取到的id为undefined,你当前DataById里的useEffect虽然写了默认id,但实际调用getDataById时没有判断路由id是否存在的逻辑,且你写死的传参和路由id逻辑冲突。 - 代码存在无效冗余内容:HomePage函数顶部的
<DataById/>、各组件里未定义的usePrevious变量都是无效代码,可直接删除。
解决方案
1. 修正App.js路由配置
import React from "react"; import "./style/App.css"; import { BrowserRouter, Switch, Route } from "react-router-dom"; import HomePage from "./components/homePage" import PostJournalEntry from "./components/postJournalEntry" function App() { return ( <div className="app"> <BrowserRouter> <Switch> <Route path="/postJournal" exact component = {PostJournalEntry}/> {/* 路径加?表示id是可选参数,/和/xxx都会匹配到HomePage */} <Route path="/:id?" exact component = {HomePage}/> </Switch> </BrowserRouter> </div> ); } export default App;
2. 修正HomePage组件代码
清理无效代码,调整为左右分栏布局:
import React, { useState, useEffect } from "react"; import { Link } from "react-router-dom"; import Axios from "axios"; import HomePageListItems from "./homePageListItems"; import DataById from "./dataById"; export default function HomePage(props){ const [getAllData, setGetAllData] = useState() const getData =async () => { await Axios.get("http://localhost:5000/get").then((response)=>{ setGetAllData(response.data) }) .catch((error)=>{console.log(error)}) } useEffect(()=>{ getData(); },[]) return( <section style={{display: 'flex', gap: '20px'}}> {/* 左侧列表区域 */} <div style={{width: '30%'}}> <Link to = "/postJournal">Post Journal Entry</Link> {getAllData&&getAllData.map((item)=>{ return( <HomePageListItems key={item.id} idx={item.id} name={item.name} title={item.title} journalEntry={item.journalEntry} date={item.date} file={item.file} /> ) })} </div> {/* 右侧详情区域 */} <div style={{width: '70%'}}> <DataById allBlogData={getAllData}/> </div> </section> ) }
示例内联样式可以替换为你自己的类名样式,同时将全量博客数据传给详情组件,可避免重复发请求。
3. 修正DataById组件逻辑
增加默认id判断,路由无id时自动使用预设id,id变化时自动重新加载详情:
import React, { useState, useEffect } from "react"; import { useParams } from "react-router-dom"; import Axios from "axios"; // 替换为你自己的默认博客id const DEFAULT_BLOG_ID = "35b48be0-0ab8-4409-a5eb-a0c4dbd0a4b3"; export default function DataById({allBlogData}){ const [axiosGetData, setAxiosGetData] = useState({}) const {id} = useParams() // 优先取路由id,没有就用默认id const targetId = id || DEFAULT_BLOG_ID; const getDataById =async (reqId) => { // 可选优化:如果已经有全量数据,直接从列表中匹配,不用发请求 if(allBlogData) { const target = allBlogData.find(item => item.id === reqId); if(target) { setAxiosGetData(target); return; } } // 全量数据未加载/未匹配到对应数据时再发起请求 await Axios.get(`http://localhost:5000/${reqId}`).then((response)=>{ setAxiosGetData(response.data[0]) }) .catch((error)=>{console.log(error)}) } useEffect(()=>{ if(targetId) { getDataById(targetId); } },[targetId, allBlogData]) return( <> <p> DataByID</p> name:{axiosGetData.name} Date:{axiosGetData.date} Journal:{axiosGetData.journalEntry} </> ) }
4. 清理HomePageListItems组件无效代码
直接删除组件内未定义的usePrevious变量即可,其余逻辑不用修改。
效果验证
- 首次打开
/路径时,会自动用预设的默认id加载对应博客详情 - 点击左侧列表项跳转到
/xxx路径时,targetId会自动更新为路由id,触发详情重新加载 - 共用全量数据的逻辑可减少重复请求,提升加载速度
内容的提问来源于stack exchange,提问作者Brute
相关产品推荐
相关产品推荐

