ReactJS结合AG Grid如何实现每次仅播放数组中的单个视频
问题原因
现有代码存在4个核心问题导致点击播放按钮异常:
- 状态职责混乱:用同一个
response状态既存接口返回的全量视频列表,又存点击时的临时数据,没有单独存储当前待播放的单个视频地址 - iframe播放地址取值错误:弹窗里的视频地址取的是父组件传入的
id参数,和当前点击的行数据完全没有关联 - AG Grid组件缺少必要绑定:写了
columnDefs和onGridReady逻辑但没有绑定到表格组件上,表格初始化逻辑异常 - 语法错误:Dialog组件缺失开标签,JSX结构不完整
修复步骤
- 新增独立状态
currentVideoUrl,专门存储当前点击行对应的单个视频地址,和全量列表数据完全隔离 - 修改按钮点击逻辑:点击Play按钮时,只提取当前行数据里的
Video_Name字段赋值给currentVideoUrl,再打开弹窗 - 补全AG Grid组件的属性绑定,正确传入列配置和就绪回调
- 把iframe的src属性改为绑定
currentVideoUrl,关闭弹窗时清空这个状态 - 补全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
相关产品推荐
相关产品推荐

