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

React循环中Modal批量弹出问题:如何按ID打开对应弹窗?

问题:循环中的React弹窗点击后全部打开,需按ID打开对应弹窗

问题场景

实现React弹窗后,将Modal置于循环中,点击任意按钮会打开所有弹窗,需要实现点击按钮仅打开对应ID的弹窗。

原代码问题分析

原useModal钩子使用单个布尔值isShown控制所有弹窗的显示状态,循环内的所有Modal都绑定同一个状态,导致点击时所有弹窗同时触发显示。

修改方案

1. 更新useModal钩子

将状态从单个布尔值改为跟踪当前激活的弹窗ID(null表示无弹窗打开):

import { useState } from 'react';

export const useModal = () => {
  const [activeModalId, setActiveModalId] = useState<string | null>(null);

  const openModal = (id: string) => setActiveModalId(id);
  const closeModal = () => setActiveModalId(null);
  const isModalShown = (id: string) => activeModalId === id;

  return {
    openModal,
    closeModal,
    isModalShown
  };
};

2. 修改Alert组件

使用新的useModal方法,给每个按钮绑定对应弹窗的ID,Modal根据ID判断是否显示:

export default function Alert({}: Props) {
  const { alerts, loading } = useGetAlerts();
  const { openModal, closeModal, isModalShown } = useModal();

  return (
    <div className={styles.alertHeader}>
      <div className={styles.title}>Alerts</div>
      <div className={styles.alertFrame}>
        <div className={styles.counter}>{`${alerts?.items.length}`}</div>
        <div className={styles.titleFrame}>
          <div className={styles.summaryTitle}>
            Outstanding <br></br>Alerts
          </div>
        </div>
      </div>
      {loading ? (
        <SnakeLoader />
      ) : (
        alerts?.items.slice(0, 5).map((a) => (
          <div key={`id_${a.id}`} className={styles.alertFrame}>
            <div className={styles.titleFrame} id="titleFrame">
              <div className={styles.alertTitle} id="alertTitle">
                {' '}
                {`${a.message}`}{' '}
              </div>
              <div className={styles.alertLink} id="alertLink">
                <button onClick={() => openModal(a.id)}>Click for More</button>
                <Modal
                  isShown={isModalShown(a.id)}
                  hide={closeModal}
                  modalContent={a.message}
                  headerText={a.id}
                />
              </div>
            </div>
            <div className={styles.alertClose} id="alertClose">
              X
            </div>
          </div>
        ))
      )}
    </div>
  );
}

3. Modal组件无需修改

原Modal组件逻辑保持不变,它仅负责接收isShown状态和hide方法,现在传入的isShown是针对单个弹窗的判断结果。

核心思路

通过跟踪当前激活的弹窗ID,替代全局布尔状态,让每个Modal独立判断自身是否需要显示,从而实现点击按钮仅打开对应ID的弹窗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 18:05:25