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

React中如何将{todo.title}设为可点击并通过Link路由传参

如何在React中使用Link组件实现可点击的Todo标题并路由传参

步骤说明

修改后的完整代码

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;

关键修改点说明

  1. 路由基础配置:
    • 用BrowserRouter包裹整个应用,使Link组件能正常触发路由跳转;React Router v6+需用Routes包裹所有Route规则。
  2. Link组件传参:
    • 通过to={/todo/${todo.id}}生成带动态ID的路由路径,点击后URL会变为/todo/1、/todo/2这类格式。
  3. 详情页获取参数:
    • 在TodoDetail组件中使用useParams()钩子提取URL中的id参数,以此请求对应Todo的详情数据。
  4. UI与数据同步:
    • 给复选框添加checked={todo.completed}属性,确保显示状态与本地数据一致;更新todo状态后,同步修改本地todos数组,实时刷新列表UI。

内容的提问来源于stack exchange,提问作者joel noronha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 21:20:20