React中为JSON对象添加链接并实现跳转后数据展示
解决方案
我会一步步帮你实现需求,包括让表格里的名称变成可跳转链接、创建详情页展示对应数据,还会修复你当前搜索框的问题(三个输入框共用一个状态会导致输入互相干扰)。
1. 安装并配置React Router
首先需要用React Router实现单页应用的页面跳转,先安装依赖:
npm install react-router-dom
然后在你的根组件(比如App.js)里配置路由规则:
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import Stocks from './Stocks'; // 你的表格组件 import StockDetail from './StockDetail'; // 即将创建的详情页组件 function App() { return ( <Router> <Routes> <Route path="/" element={<Stocks />} /> <Route path="/stock/:name" element={<StockDetail />} /> </Routes> </Router> ); } export default App;
2. 修改你的Stocks组件
主要做三件事:拆分搜索框状态、把名称改成可跳转链接、修正key的位置(key应该放在<tr>上而非<td>):
import React, { Component } from "react"; import { Link } from 'react-router-dom'; export default class Stocks extends Component { constructor(props) { super(props); this.state = { items: [], isLoaded: false, symbolSearch: "", industrySearch: "", historySearch: "", }; } // 分别处理三个搜索框的输入 updateSymbolSearch(event) { this.setState({ symbolSearch: event.target.value }); } updateIndustrySearch(event) { this.setState({ industrySearch: event.target.value }); } updateHistorySearch(event) { this.setState({ historySearch: event.target.value }); } componentDidMount() { fetch("http://131.181.190.87:3001/all") .then((res) => res.json()) .then((json) => { this.setState({ isLoaded: true, items: json, }); }); } render() { // 根据三个独立的搜索条件过滤数据 let filteredItems = this.state.items.filter((item) => { const matchesSymbol = item.symbol.toUpperCase().includes(this.state.symbolSearch.toUpperCase()); const matchesIndustry = item.industry.includes(this.state.industrySearch); // 这里可以根据你的需求调整history搜索的过滤逻辑 const matchesHistory = item.symbol.toUpperCase().includes(this.state.historySearch.toUpperCase()) || item.industry.includes(this.state.historySearch); // 若需要三个条件任意满足一个,就把&&改成|| return matchesSymbol && matchesIndustry && matchesHistory; }); var { isLoaded } = this.state; if (!isLoaded) { return <div>Loading...</div>; } else { return ( <div> <form className="form-for-table-search"> SelectSymbol:   <input type="text" value={this.state.symbolSearch} onChange={this.updateSymbolSearch.bind(this)} />    {" "} <button type="button" className="btn-submit"> Search </button> <br />   Industry:       <input type="text" value={this.state.industrySearch} onChange={this.updateIndustrySearch.bind(this)} /> <button type="button" className="btn-submit"> Search </button>     History of Symbol and date :       <input type="text" value={this.state.historySearch} onChange={this.updateHistorySearch.bind(this)} />     <button type="button" className="btn-submit"> Search </button> </form> <table border={2} cellPadding={1}> <thead> <tr> <th>Symbol</th> <th>Name</th> <th>Industry</th> </tr> </thead> <tbody> {filteredItems.map((item) => ( <tr key={item.symbol}> <td>{item.symbol}</td> <td> {/* 将名称转为可跳转的链接,传递name参数到详情页 */} <Link to={`/stock/${item.name}`}>{item.name}</Link> </td> <td>{item.industry}</td> </tr> ))} </tbody> </table> </div> ); } } }
3. 创建详情页组件StockDetail.js
这个组件会接收路由参数里的名称,调用对应API获取数据并展示成表格:
import React, { Component } from "react"; import { useParams } from 'react-router-dom'; // 类组件无法直接使用useParams,用函数组件包裹获取路由参数 class StockDetailComponent extends Component { constructor(props) { super(props); this.state = { detail: [], isLoaded: false, }; } componentDidMount() { const { name } = this.props; // 替换为你的详情API地址 fetch(`http://131.181.190.87:3001/name?=${name}`) .then((res) => res.json()) .then((json) => { this.setState({ isLoaded: true, detail: json, }); }) .catch(err => { console.error('获取详情数据失败:', err); this.setState({ isLoaded: true }); }); } render() { const { isLoaded, detail } = this.state; if (!isLoaded) { return <div>Loading detail...</div>; } if (!detail.length) { return <div>No data found for this name.</div>; } // 自动生成表头(根据返回数据的字段) const headers = Object.keys(detail[0]); return ( <div> <h2>Stock Detail: {this.props.name}</h2> <table border={2} cellPadding={1}> <thead> <tr> {headers.map(header => <th key={header}>{header}</th>)} </tr> </thead> <tbody> {detail.map((item, index) => ( <tr key={index}> {headers.map(header => <td key={header}>{item[header]}</td>)} </tr> ))} </tbody> </table> </div> ); } } function StockDetail() { const params = useParams(); return <StockDetailComponent name={params.name} />; } export default StockDetail;
额外注意事项
- 请确保你的详情API地址是正确的,我暂时用了示例地址,记得替换成实际接口
- 搜索框的过滤逻辑可以根据你的需求调整(比如改成任意条件满足即可)
- 如果需要让Symbol列也可跳转,只需要把Symbol列的
<td>换成<Link>组件,逻辑和Name列一致
内容的提问来源于stack exchange,提问作者Hemlata
相关产品推荐
相关产品推荐

