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

React中通过回调按钮触发异步Fetch重渲染组件的实现

React点击按钮刷新加密货币API数据的实现方案

我是React新手,正在开发一款加密货币策略计算应用,已完成API开发,需要实现类似币安转换页面的功能:点击「ACTUALIZAR」按钮时,触发异步Fetch获取最新数据并重新渲染组件。希望全程使用React实现,不引入额外库。

API返回的JSON结构如下:

{"response": "1","remesaspatria": {"LTCUSD": "60.990000000000002","LTCEUR": "60.178832999999997"},"Binance_LTCUSD": {"mins": 5,"price": "61.03271805"},"patriaexchange": {"BSPTR": "421,99","PTRBTC": "415,46134749","PTRLTC": "1,13874534","USDPTR": "53,73","USDBTC": "22.324,64","USDLTC": "61,19","BSUSD": "7,98"},"monitorweb": {"BCV": "7,984","ENPARALELOV": "8,10","DOLARTODAY": "8,16","MONITORWEB": "8,17"}}

现有代码:
app.js:

import React, { useState, useEffect } from 'react'
import { useFetch } from './fetchData'

const PillContents = (n) => {
  const data ='https://api.mysite.site/?site=crypto&apikey=mykey' // API URL
  const { loading, apiData } = useFetch(data)

  const [valuesC, setValuesC] = useState({ refB: 'hidden' })

  const handleCalc = () => {
    setValuesC({ ...valuesC, refB: '' })
  }
  const handleRef = () => {
    ... here is going to be a update vars function  ...
  }
  return (
    <MDBRow>
      <MDBCol md='6' className='mb-4'>
        <form>
          <MDBRow className='mb-4'>
              <MDBBtn className='mb-4' type='button' id='calc' onClick={handleCalc}>
                CALCULAR
              </MDBBtn>
              <MDBTooltip tag='span' wrapperClass='d-inline-block' placement='top' title='Actualizar precios'>
                <MDBBtn className={`mb-4 ${valuesC.refB}`} type='button' style={{ marginLeft: 5 }} id='refc'
                  onClick={handleRef}>
                  ACTUALIZAR
              </MDBBtn>
            </MDBTooltip>
          </MDBRow>
        </form>
      </MDBCol>
    </MDBRow>
  )
}

fetchdata.js:

import { useState, useEffect } from 'react'

export const useFetch = (url) => {
  const [apiData, setApiData] = useState([])
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    // Async request
    const getData = async () => {
      const response = await fetch(url)
      const apiData = await response.json()
      setApiData(apiData)
      setLoading(false)
    }
    getData()
  }, [url])
  return { loading, apiData }
}

方案说明

原useFetch Hook仅在url变化时自动触发请求,要实现手动点击刷新,需给Hook添加可手动调用的刷新函数,通过修改依赖项触发重新请求。

修改后的代码

1. 更新fetchdata.js

给useFetch添加refresh函数,通过无关状态变量refreshTrigger触发useEffect重新执行:

import { useState, useEffect } from 'react'

export const useFetch = (url) => {
  const [apiData, setApiData] = useState([])
  const [loading, setLoading] = useState(true)
  // 新增触发刷新的状态变量
  const [refreshTrigger, setRefreshTrigger] = useState(0)

  // 封装请求逻辑为独立函数
  const getData = async () => {
    setLoading(true)
    try {
      const response = await fetch(url)
      const data = await response.json()
      setApiData(data)
    } catch (error) {
      console.error('请求失败:', error)
      // 可按需添加错误提示逻辑
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    getData()
  }, [url, refreshTrigger]) // 依赖项加入refreshTrigger

  // 手动刷新函数:修改trigger值触发useEffect重新执行请求
  const refresh = () => {
    setRefreshTrigger(prev => prev + 1)
  }

  return { loading, apiData, refresh }
}

2. 更新app.js

在组件中获取refresh函数,并在handleRef中调用:

import React, { useState } from 'react'
import { useFetch } from './fetchData'

const PillContents = (n) => {
  const data ='https://api.mysite.site/?site=crypto&apikey=mykey' // API URL
  // 解构出refresh函数
  const { loading, apiData, refresh } = useFetch(data)

  const [valuesC, setValuesC] = useState({ refB: 'hidden' })

  const handleCalc = () => {
    setValuesC({ ...valuesC, refB: '' })
  }
  
  // 点击刷新按钮时调用refresh函数
  const handleRef = () => {
    refresh()
  }

  return (
    <MDBRow>
      <MDBCol md='6' className='mb-4'>
        <form>
          <MDBRow className='mb-4'>
              <MDBBtn className='mb-4' type='button' id='calc' onClick={handleCalc}>
                CALCULAR
              </MDBBtn>
              <MDBTooltip tag='span' wrapperClass='d-inline-block' placement='top' title='Actualizar precios'>
                <MDBBtn className={`mb-4 ${valuesC.refB}`} type='button' style={{ marginLeft: 5 }} id='refc'
                  onClick={handleRef}>
                  {/* 加载中动态修改按钮文本 */}
                  {loading ? 'ACTUALIZANDO...' : 'ACTUALIZAR'}
              </MDBBtn>
            </MDBTooltip>
          </MDBRow>
        </form>
        {/* 示例:展示最新LTC价格 */}
        {apiData?.Binance_LTCUSD && (
          <div className='mt-3'>
            <p>Binance LTC/USD: {apiData.Binance_LTCUSD.price}</p>
          </div>
        )}
      </MDBCol>
    </MDBRow>
  )
}

关键改动说明

  • 在useFetch中新增refreshTrigger状态,每次调用refresh时通过改变其值触发useEffect重新执行请求。
  • 将请求逻辑封装为getData函数,添加try/catch错误处理,并在请求前后更新loading状态,优化用户感知。
  • 刷新按钮根据loading状态动态显示文本,提升交互体验。
  • 可按需添加数据展示区域,使用更新后的apiData渲染内容。

内容的提问来源于stack exchange,提问作者Alec G.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 02:10:18