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

如何实现React中Axios请求仅在点击打开Bootstrap Modal时触发

问题根因

你当前的代码提前发起请求的核心原因有两个:

  • <ComparisonModal> 组件是随父页面一同渲染挂载的,而你写的空依赖数组的useEffect会在组件挂载完成后立刻执行,所以无论用户是否点击打开模态框,请求都会在页面加载时直接触发。
  • 你用了Bootstrap原生的data-bs-*属性控制模态框显隐,React层无法感知模态框的开关状态,没法和请求逻辑做联动。

最优实现方案

推荐用React状态控制模态框的显隐逻辑,配合条件渲染实现请求按需触发,完整实现步骤如下:

1. 父组件新增状态管理

父组件新增两个状态,分别控制模态框是否展示、存储当前选中的行ID:

// 父组件顶部引入useState
import { useState } from 'react';

// 父组件内部定义状态
const [showModal, setShowModal] = useState(false);
const [selectedRowId, setSelectedRowId] = useState(null);

// 改造rowEvents方法
const rowEvents = (id) => {
  setSelectedRowId(id);
  setShowModal(true);
  // 原有rowEvents的其他逻辑保留
};

修改触发按钮的代码,删掉原生的data-bs-*控制属性:

<td>
  <button type="button" onClick={() => rowEvents(id)}>
    Compare
  </button>
</td>

父组件渲染模态框的位置改成条件渲染,只有showModal为true时才加载Modal组件:

{
  showModal && 
  <ComparisonModal 
    previousWon={previousWon} 
    currentWon={currentWon} 
    rowId={selectedRowId}
    onClose={() => setShowModal(false)}
  />
}

2. 改造ComparisonModal组件

在Modal组件内初始化Bootstrap模态框实例,监听关闭事件同步父组件状态,同时保留你的请求逻辑:

import { useEffect, useRef } from 'react';
import * as bootstrap from 'bootstrap';

const ComparisonModal = ({ previousWon, currentWon, rowId, onClose }) => {
  const modalRef = useRef(null);
  const modalInstanceRef = useRef(null);

  // 初始化模态框实例,监听关闭事件
  useEffect(() => {
    modalInstanceRef.current = new bootstrap.Modal(modalRef.current);
    modalInstanceRef.current.show();

    // 同步模态框原生关闭事件到父组件
    const handleModalClose = () => onClose();
    modalRef.current.addEventListener('hidden.bs.modal', handleModalClose);

    // 组件销毁时清理实例和事件
    return () => {
      modalRef.current.removeEventListener('hidden.bs.modal', handleModalClose);
      modalInstanceRef.current?.dispose();
    };
  }, [onClose]);

  // 请求逻辑,只有组件挂载(用户点击打开模态框)时才会触发
  useEffect(() => {
    async function fetchData() {
      // 可以用传入的rowId发起对应请求
      const content = await client.get(`你的接口地址/${rowId}`);
      // 后续处理返回数据的逻辑保留
    }
    fetchData();
  }, [rowId]);

  return (
    <div 
      className="modal fade" 
      ref={modalRef} 
      data-bs-backdrop="static" 
      data-bs-keyboard="false" 
      tabIndex="-1" 
      aria-hidden="true"
    >
      {/* 你原有模态框的modal-dialog、modal-content等内容全部保留 */}
    </div>
  );
};

export default ComparisonModal;

其他可选方案

如果你不需要每次打开模态框都重新加载组件,可以不用条件渲染,直接给Modal组件传入show状态,把show加入请求useEffect的依赖即可:

// Modal组件内的请求逻辑改造
useEffect(() => {
  if (!show) return; // 模态框未打开时不发起请求
  async function fetchData() {
    const content = await client.get('1');
  }
  fetchData();
}, [show]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 21:06:04