React中如何将{todo.title}设为可点击并通过Link路由传参
如何在React中使用Link组件实现可点击的Todo标题并路由传参
步骤说明
- 导入React Router核心组件:从
react-router-dom中导入Link和BrowserRouter(必须用路由容器包裹才能使用Link功能)。 - 替换标签为Link组件:用
<Link>替代原有<a>标签,通过to属性指定带Todo ID的路由路径,实现无刷新跳转。 - 配置详情页路由:添加路由规则,匹配带ID参数的路径,指向详情页面组件。
- 修复fetch请求的URL错误:原代码中更新todo状态的请求URL未替换实际ID,需用模板字符串插入动态ID。
修改后的完整代码
import 'bootstrap/dist/css/bootstrap.min.css'; import React, { useEffect, useState } from 'react'; import { BrowserRouter as Router, Route, Link, Routes, useParams } from 'react-router-dom'; import './App.css'; // 详情页组件:展示单条Todo的详细信息 const TodoDetail = () => { const { id } = useParams(); const [todo, setTodo] = useState(null); useEffect(() => { fetch(`https://jsonplaceholder.typicode.com/todos/${id}`) .then(res => res.json()) .then(data => setTodo(data)); }, [id]); if (!todo) return <div>加载中...</div>; return ( <div className="container mt-5"> <h2>Todo详情</h2> <p><strong>ID:</strong> {todo.id}</p> <p><strong>标题:</strong> {todo.title}</p> <p><strong>状态:</strong> {todo.completed ? '已完成' : '未完成'}</p> <Link to="/">返回列表</Link> </div> ); }; function App() { const [todos, setTodos] = useState([]); const fetchData = () => { fetch(`https://jsonplaceholder.typicode.com/todos?userId=1`) .then((response) => response.json()) .then((actualData) => setTodos(actualData)); }; const updateData = (e) => { const id = e.target.id; const checked = e.target.checked; fetch(`https://jsonplaceholder.typicode.com/todos/${id}`, { method: 'PATCH', body: JSON.stringify({ completed: checked }), headers: { 'Content-type': 'application/json; charset=UTF-8' }, }) .then((response) => response.json()) .then(() => { // 本地状态更新,同步UI显示 setTodos(prev => prev.map(todo => todo.id === parseInt(id) ? {...todo, completed: checked} : todo )); }); }; useEffect(() => fetchData(), []); return ( <Router> <Routes> {/* 列表页路由 */} <Route path="/" element={ <div className="window d-flex flex-column justify-content-center align-items-center"> <div className="d-flex flex-column align-items-center bg-info rounded border border-danger"> <div className="p-2"><h1>todo list</h1></div> <div className="p-2 border border-danger"> <ul className="list-group"> {todos.map((todo) => <li className="list-group-item d-flex justify-content-between align-items-center" key={todo.id}> {/* 使用Link组件跳转至详情页,携带ID参数 */} <Link to={`/todo/${todo.id}`}>{todo.title}</Link> <input type='checkbox' id={todo.id} onChange={updateData} checked={todo.completed} // 同步复选框与数据状态 /> </li>) } </ul> </div> </div> </div> } /> {/* 详情页路由,:id为动态参数 */} <Route path="/todo/:id" element={<TodoDetail />} /> </Routes> </Router> ); } export default App;
关键修改点说明
- 路由基础配置:
- 用
BrowserRouter包裹整个应用,使Link组件能正常触发路由跳转;React Router v6+需用Routes包裹所有Route规则。
- 用
- Link组件传参:
- 通过
to={/todo/${todo.id}}生成带动态ID的路由路径,点击后URL会变为/todo/1、/todo/2这类格式。
- 通过
- 详情页获取参数:
- 在
TodoDetail组件中使用useParams()钩子提取URL中的id参数,以此请求对应Todo的详情数据。
- 在
- UI与数据同步:
- 给复选框添加
checked={todo.completed}属性,确保显示状态与本地数据一致;更新todo状态后,同步修改本地todos数组,实时刷新列表UI。
- 给复选框添加
内容的提问来源于stack exchange,提问作者joel noronha
相关产品推荐
相关产品推荐

