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

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: &emsp;
            <input
              type="text"
              value={this.state.symbolSearch}
              onChange={this.updateSymbolSearch.bind(this)}
            />
            &emsp; &emsp;{" "}
            <button type="button" className="btn-submit">
              Search
            </button>
            <br />
            &emsp; Industry: &emsp; &emsp; &emsp;
            <input
              type="text"
              value={this.state.industrySearch}
              onChange={this.updateIndustrySearch.bind(this)}
            />
            <button type="button" className="btn-submit">
              Search
            </button>
            &emsp; &emsp; History of Symbol and date : &emsp; &emsp; &emsp;
            <input
              type="text"
              value={this.state.historySearch}
              onChange={this.updateHistorySearch.bind(this)}
            />
            &emsp; &emsp;
            <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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 15:48:00