React实现点击列表事件项跳转至对应单条详情页的方法
React 列表点击跳转单条详情页实现方法
实现总共分3个核心步骤,完全适配你当前使用的React Router v6语法:
1. 配置动态路由
首先在路由配置文件中新增详情页的动态路由规则,用动态参数承载单条数据的唯一ID:
// 路由配置文件示例(如App.jsx) import { BrowserRouter, Routes, Route } from 'react-router-dom' import Dashboard from './Dashboard' import EventDetail from './EventDetail' import Login from './Login' function App() { return ( <BrowserRouter> <Routes> <Route path="/login" element={<Login />} /> <Route path="/dashboard" element={<Dashboard />} /> {/* 新增详情页动态路由,:eventId为参数占位符 */} <Route path="/events/:eventId" element={<EventDetail />} /> </Routes> </BrowserRouter> ) } export default App
2. 修改Dashboard组件,添加点击跳转逻辑
在列表渲染时给每个条目绑定点击事件,点击后携带当前条目的ID跳转到对应详情路由:
import { useNavigate, Navigate } from 'react-router-dom' // 其余import保持你原有代码不变 function Dashboard() { const [token, setToken] = useContext(store) const [events, setEvents] = useState([]) // 新增路由跳转钩子 const navigate = useNavigate() useEffect(()=>{ axios.get('http://localhost:5000/api/events').then(res => { console.log(res) setEvents(res.data) }).catch(err => {console.log(err)}) }, []) if(!token){ return ( <Navigate to="/login" replace={true} /> ) } return ( <> <div className='eventelement'> <ul> { events.map(event => ( <section className=''> {/* 给列表项绑定点击事件,加指针样式提示可点击 */} <li key={event._id} onClick={() => navigate(`/events/${event._id}`)} style={{cursor: 'pointer'}} > <table className='eventtable' border={1}> <th className='eventth'><div className='eventtitle'> {event.eventname} </div></th> {/* 注意:原代码此处hosted by对应event._id是逻辑错误,记得替换成主办方对应字段,如event.hoster */} <tr><div className='eventhoster'> hosted by: {event._id} </div></tr> <tr><div className='eventdetails'> <label className='eventsh'>Event type: </label>{event.eventtype} </div></tr> </table> </li><br /> </section> )) } </ul> </div> <div> </div> </> ) } export default Dashboard
3. 编写详情页组件,获取并渲染单条数据
新建EventDetail组件,从路由参数中拿到当前条目ID,调用接口拉取单条详情数据渲染即可:
import { useParams, Navigate } from 'react-router-dom' import { useState, useEffect, useContext } from 'react' import axios from 'axios' import { store } from './store' // 替换成你自己的store文件路径 function EventDetail() { const [token] = useContext(store) // 读取路由中的动态参数eventId const { eventId } = useParams() const [eventDetail, setEventDetail] = useState(null) const [loading, setLoading] = useState(true) useEffect(() => { // 调用后端单条详情接口,替换成你自己的后端接口路径 axios.get(`http://localhost:5000/api/events/${eventId}`) .then(res => { setEventDetail(res.data) setLoading(false) }) .catch(err => { console.log(err) setLoading(false) }) }, [eventId]) if(!token) { return <Navigate to="/login" replace={true} /> } if(loading) { return <div>加载中...</div> } if(!eventDetail) { return <div>该事件不存在</div> } // 按需自定义详情页渲染结构 return ( <div className='event-detail-page'> <h1>{eventDetail.eventname}</h1> <p>主办方:{eventDetail.hoster}</p> <p>事件类型:{eventDetail.eventtype}</p> {/* 其余字段按业务需求渲染 */} </div> ) } export default EventDetail
可选优化方案
- 若不想额外发详情请求,可以在跳转时直接把当前event对象通过路由state传递:
navigate(/events/${event._id}, {state: {event}}),详情页通过const location = useLocation()取location.state.event即可拿到数据。注意这种方式刷新页面后state会丢失,需要配合接口请求做兜底。 - 可以给列表项加hover高亮样式,强化可点击的交互感知。
内容的提问来源于stack exchange,提问作者Venkat
相关产品推荐
相关产品推荐

