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

如何实现表格多行关联单个Dialog展示数据?

解决方案

核心思路

将Dialog的显示状态、当前要加载的ID统一放在父组件App.tsx中管理,单个Form组件仅负责根据传入的ID请求数据并渲染Dialog内容,避免创建多个组件实例。

修改后的代码

App.tsx

import * as React from 'react';
import { Form } from './Form';

export default function ScrollDialog() {
  const [dialogOpen, setDialogOpen] = React.useState(false);
  const [currentTodoId, setCurrentTodoId] = React.useState<number>(0);

  // 处理表格行按钮点击:设置当前ID并打开Dialog
  const handleRowClick = (id: number) => {
    setCurrentTodoId(id);
    setDialogOpen(true);
  };

  const handleDialogClose = () => {
    setDialogOpen(false);
  };

  return (
    <div>
      <table border={1}>
        <thead>
          <tr>
            <th>Name</th>
            <th>Input Data</th>
            <th>Button</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>a</td>
            <td>1</td>
            <td>
              <button onClick={() => handleRowClick(1)}>Get Data</button>
            </td>
          </tr>
          <tr>
            <td>b</td>
            <td>2</td>
            <td>
              <button onClick={() => handleRowClick(2)}>Get Data</button>
            </td>
          </tr>
          <tr>
            <td>c</td>
            <td>3</td>
            <td>
              <button onClick={() => handleRowClick(3)}>Get Data</button>
            </td>
          </tr>
        </tbody>
      </table>
      {/* 传入Dialog状态、当前ID和关闭回调 */}
      <Form 
        id={currentTodoId} 
        open={dialogOpen} 
        onClose={handleDialogClose} 
      />
    </div>
  );
}

Form.tsx

import React, { useState, useEffect, useRef } from 'react';
import Button from '@mui/material/Button';
import Dialog, { DialogProps } from '@mui/material/Dialog';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import DialogContentText from '@mui/material/DialogContentText';
import DialogTitle from '@mui/material/DialogTitle';
import useMediaQuery from '@mui/material/useMediaQuery';
import { useTheme } from '@mui/material/styles';

// 定义组件Props类型
type FormProps = {
  id: number;
  open: boolean;
  onClose: () => void;
};

export const Form = ({ id, open, onClose }: FormProps) => {
  const [todoId, setTodoId] = useState<string>('');
  const [todoTitle, setTodoTitle] = useState<string>('');
  const theme = useTheme();
  const fullScreen = useMediaQuery(theme.breakpoints.down('md'));
  const descriptionElementRef = useRef<HTMLElement>(null);

  // 当ID变化时,请求对应数据
  useEffect(() => {
    if (id === 0) return; // 初始ID为0时不请求

    const fetchTodoData = async () => {
      try {
        const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${id}`);
        const data = await response.json();
        setTodoId(data.id.toString());
        setTodoTitle(data.title);
      } catch (error) {
        console.error('请求数据失败:', error);
      }
    };

    fetchTodoData();
  }, [id]);

  // Dialog打开时聚焦描述文本
  useEffect(() => {
    if (open && descriptionElementRef.current) {
      descriptionElementRef.current.focus();
    }
  }, [open]);

  return (
    <Dialog
      fullScreen={fullScreen}
      open={open}
      scroll="body"
      aria-labelledby="scroll-dialog-title"
      aria-describedby="scroll-dialog-description"
    >
      <DialogTitle id="scroll-dialog-title">Todo 详情</DialogTitle>
      <DialogContent dividers>
        <DialogContentText
          id="scroll-dialog-description"
          ref={descriptionElementRef}
          tabIndex={-1}
        >
          ID: {todoId}
          <br />
          标题: {todoTitle}
        </DialogContentText>
      </DialogContent>
      <DialogActions>
        <Button onClick={onClose}>关闭</Button>
      </DialogActions>
    </Dialog>
  );
};

关键修改说明

  1. 状态提升:将Dialog的open状态和当前要加载的currentTodoId移到父组件App.tsx,确保单个Form组件能响应所有行的点击事件。
  2. 表格按钮逻辑:每行按钮点击时,将该行的Input Data作为ID传入handleRowClick,设置当前ID并打开Dialog。
  3. Form组件职责简化:移除Form内部的按钮和独立的open状态,仅负责接收父组件传递的状态、ID和回调,专注于数据请求和Dialog渲染。
  4. 动态请求URL:将请求URL中的硬编码1替换为传入的id,实现根据不同ID加载对应数据。
  5. 错误处理:添加请求失败的错误捕获,避免程序崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 22:25:13