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

ReactJS结合AG Grid如何实现每次仅播放数组中的单个视频

问题原因

现有代码存在4个核心问题导致点击播放按钮异常:

  • 状态职责混乱:用同一个response状态既存接口返回的全量视频列表,又存点击时的临时数据,没有单独存储当前待播放的单个视频地址
  • iframe播放地址取值错误:弹窗里的视频地址取的是父组件传入的id参数,和当前点击的行数据完全没有关联
  • AG Grid组件缺少必要绑定:写了columnDefs和onGridReady逻辑但没有绑定到表格组件上,表格初始化逻辑异常
  • 语法错误:Dialog组件缺失开标签,JSX结构不完整
修复步骤
  1. 新增独立状态currentVideoUrl,专门存储当前点击行对应的单个视频地址,和全量列表数据完全隔离
  2. 修改按钮点击逻辑:点击Play按钮时,只提取当前行数据里的Video_Name字段赋值给currentVideoUrl,再打开弹窗
  3. 补全AG Grid组件的属性绑定,正确传入列配置和就绪回调
  4. 把iframe的src属性改为绑定currentVideoUrl,关闭弹窗时清空这个状态
  5. 补全Dialog开标签,修正JSX语法错误
修复后完整代码
import React, { useState } from 'react';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-alpine.css';
import { Button, Dialog, DialogActions, DialogContent } from '@mui/material';

const initialValue = { Name: "", Floor: "", Group: "", Camera: "", Videos: "" };

export default function App(data, handleFormSubmit) {
  // 单独存储当前要播放的视频地址,和列表数据分离
  const [currentVideoUrl, setCurrentVideoUrl] = useState("");
  const [open, setOpen] = React.useState(false);
  const [formData, setFormData] = useState(initialValue);
  // 单独存储表格全量数据,和当前播放地址状态隔离
  const [rowData, setRowData] = useState([]);

  const actionButton = (params) => {
    // 只取当前点击行的视频地址,不会影响其他行
    setCurrentVideoUrl(params.data.Video_Name);
    setOpen(true);
  };

  const handleClose = () => {
    setOpen(false);
    setFormData(initialValue);
    // 关闭时清空当前播放地址,避免下次打开残留
    setCurrentVideoUrl("");
  };

  const onChange = (e) => {
    const { value, id } = e.target;
    setFormData({ ...formData, [id]: value });
  };

  const columnDefs = [
    { headerName: "Name", field: "Company_Name", filter: "agSetColumnFilter" },
    { headerName: "Floor", field: "Floor Number" },
    { headerName: "Group", field: "Group_Name" },
    { headerName: "Camera", field: "Camera_Number" },
    { headerName: "Videos", field: "Video_Name" },
    {
      headerName: "Actions",
      field: "Video_Name",
      cellRendererFramework: (params) => (
        <div>
          <Button
            variant="contained"
            size="medium"
            color="primary"
            onClick={() => actionButton(params)}
          >
            Play
          </Button>
        </div>
      ),
    },
  ];

  const onGridReady = (params) => {
    console.log("grid is ready");
    fetch("http://localhost:8000/get_all")
      .then((resp) => resp.json())
      .then((resp) => {
        console.log(resp.results);
        setRowData(resp.results);
        params.api.applyTransaction({ add: resp.results });
      });
  };

  return (
    <div className="App">
      <h1 align="center"> React FastAPI Integration</h1>
      <h3> API Data </h3>
      {/* 补全AG Grid组件的属性绑定 */}
      <div className="ag-theme-alpine" style={{ height: "400px", width: "100%" }}>
        <AgGridReact
          columnDefs={columnDefs}
          onGridReady={onGridReady}
          rowData={rowData}
        />
      </div>
      <div>
        {/* 补全Dialog开标签 */}
        <Dialog open={open} onClose={handleClose}>
          <DialogContent>
            {/* 绑定当前选中的单个视频地址 */}
            <iframe width="420" height="315" title="videos" src={currentVideoUrl} />
          </DialogContent>
          <DialogActions>
            <Button onClick={handleClose} color="secondary" variant="outlined">
              Cancel
            </Button>
            <Button
              color="primary"
              onClick={() => handleFormSubmit()}
              variant="contained"
            >
              Download
            </Button>
          </DialogActions>
        </Dialog>
      </div>
    </div>
  );
}
效果说明

修复后每次点击Play按钮,只会把当前点击行对应的视频地址存入独立状态,弹窗只会加载这一个地址的视频,不会出现同时打开多个视频窗口的问题。关闭弹窗时会清空当前播放地址,避免下次打开时加载上一次的视频残留。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 08:51:58