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

React数组map渲染表格时如何调用API获取股票价格并展示

你当前的写法有两个核心问题:

  1. JSX里直接定义的匿名函数不会被React自动执行,不会返回任何内容到视图
  2. fetch是异步请求,渲染同步执行的情况下不可能直接拿到异步返回值,同时每次组件重渲染都会重复触发请求,会严重浪费接口配额、造成页面卡顿

正确实现方案

实现思路

  • 给持仓数组的每一项新增currentPrice、loading、error字段,用来存储请求返回的当前价格、加载状态、报错信息
  • 用useEffect在组件挂载时统一触发所有股票的价格请求,请求完成后更新状态触发重渲染
  • 渲染时直接读取状态里的对应字段即可
import { useState, useEffect } from 'react'

const StockTable = () => {
  const [account, setAccount] = useState([
    {
      "Symbol": 'AAPL',
      "Shares": 1,
      "TotalCost": 130,
      "currentPrice": null,
      "loading": false,
      "error": null
    },
    {
      "Symbol": 'TSLA',
      "Shares": 1,
      "TotalCost": 1500,
      "currentPrice": null,
      "loading": false,
      "error": null
    },
  ])

  useEffect(() => {
    // 遍历所有持仓股票拉取价格
    account.forEach(stock => {
      // 已经有价格的可以跳过,避免重复请求
      if (stock.currentPrice) return
      
      // 更新加载状态
      setAccount(prev => prev.map(item => 
        item.Symbol === stock.Symbol ? {...item, loading: true} : item
      ))

      fetch(`https://finnhub.io/api/v1/quote?symbol=${stock.Symbol}&token=12345678910`)
        .then(res => res.json())
        .then(data => {
          // 请求成功更新价格
          setAccount(prev => prev.map(item => 
            item.Symbol === stock.Symbol ? {
              ...item, 
              loading: false, 
              currentPrice: data.c
            } : item
          ))
        })
        .catch(err => {
          // 请求失败更新报错
          setAccount(prev => prev.map(item => 
            item.Symbol === stock.Symbol ? {
              ...item, 
              loading: false, 
              error: '获取失败'
            } : item
          ))
        })
    })
  }, []) // 空依赖保证只在组件挂载时执行一次,需要定时刷新可以自己加定时器

  return (
    <table>
      <tbody>
        {account.map((stocks) => {
          const {Symbol , Shares, TotalCost, currentPrice, loading, error} = stocks;
          return (
            <tr key={Symbol}> {/* 注意加key属性,React列表必须 */}
              <td>{Symbol}</td>
              <td>{Shares}</td>  
              <td>${TotalCost}</td>
              <td>
                {loading ? '加载中...' : 
                 error ? error : 
                 currentPrice ? `$${currentPrice.toFixed(2)}` : '-'}
              </td>
              {/* 可自行扩展盈亏对比列 */}
              <td>
                {currentPrice ? `$${((currentPrice * Shares) - TotalCost).toFixed(2)}` : '-'}
              </td>
            </tr>
          )
        })}
      </tbody>
    </table>
  )
}

export default StockTable

注意事项

  • 不要把第三方API的token直接写在前端代码里,很容易被爬取滥用,建议自己搭建后端服务代理所有接口请求,把token存在后端
  • 如果持仓股票数量较多,可以加请求限流,避免短时间内触发过多请求被接口限流
  • 需要实时价格可以在useEffect里加定时器,定时拉取最新价格

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 01:54:08