MUI DataGrid选中行后按钮禁用状态不生效问题排查
MUI DataGrid选中行后按钮禁用状态不更新的解决方案
问题根源
- 两个DataGrid(Contacts和Leads)共用同一个
selectedRow状态,选中行操作会互相干扰,导致按钮状态逻辑混乱 - Lead表格未绑定
onSelectionModelChange事件,选中Lead行时不会触发状态更新 - Edit Lead按钮复用了Contact的编辑逻辑,路由跳转逻辑不匹配
修复方案
- 为Contacts和Leads分别维护独立的选中状态:
selectedContacts和selectedLeads - 给Lead的DataGrid绑定对应的选中事件处理函数
- 为Lead编写独立的编辑、删除点击处理函数
修复后的完整代码
import * as React from 'react'; import { useEffect, useState } from "react"; import axios from 'axios'; import AddIcon from '@mui/icons-material/Add'; import EditIcon from '@mui/icons-material/Edit'; import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline'; import FormatListNumberedRtlOutlinedIcon from '@mui/icons-material/FormatListNumberedRtlOutlined'; import { DataGrid } from '@mui/x-data-grid'; import { Container, Box, Typography, Button, Stack } from '@mui/material'; import { Link, useNavigate } from "react-router-dom"; import MyAppBar from "../components/MyAppBar"; import '../styles/init.css'; const Dashboard = () => { const [contacts, setContacts] = useState([]); const [leads, setLeads] = useState([]); // 为Contacts和Leads分别维护选中状态 const [selectedContacts, setSelectedContacts] = useState([]); const [selectedLeads, setSelectedLeads] = useState([]); const navigate = useNavigate(); useEffect(() => { const fetchAllContacts = async () => { try { const res = await axios.get('http://localhost:3000/data/contacts'); setContacts(res.data); } catch (err) { console.log(err); } }; const fetchAllLeads = async () => { try { const res = await axios.get('http://localhost:3000/data/leads'); setLeads(res.data); } catch (err) { console.log(err); } }; fetchAllContacts(); fetchAllLeads(); }, []); const contactColumns = [ { field: 'id', headerName: 'ID', width: 70 }, { field: 'person', headerName: 'Nama', width: 150, editable: true }, { field: 'person_address', headerName: 'Alamat', width: 150, editable: true }, { field: 'status', headerName: 'Status', width: 100, editable: true }, { field: 'descriptions', headerName: 'Deskripsi', width: 200, editable: true }, ]; const leadColumns = [ { field: 'id', headerName: 'ID', width: 70 }, { field: 'invoice_date', headerName: 'Invoice', width: 130, editable: true }, { field: 'sales_name', headerName: 'Nama Sales', width: 150, editable: true }, { field: 'person', headerName: 'Pelanggan', width: 150 }, { field: 'descriptions', headerName: 'Deskripsi', width: 200, editable: true }, { field: 'lead_status', headerName: 'Status Lead', width: 150, editable: true }, { field: 'notes', headerName: 'Catatan', width: 200, editable: true }, { field: 'deal_date', headerName: 'Tanggal Deal', width: 150, editable: true }, ]; // Contacts选中事件处理 const handleContactSelectionChange = (newSelection) => { setSelectedContacts(newSelection); }; // Leads选中事件处理 const handleLeadSelectionChange = (newSelection) => { setSelectedLeads(newSelection); }; const handleEditContactClick = () => { if (selectedContacts.length === 1) { navigate(`/edit_contact/${selectedContacts[0]}`); } }; const handleEditLeadClick = () => { if (selectedLeads.length === 1) { navigate(`/edit_lead/${selectedLeads[0]}`); } }; const handleDeleteContactClick = () => { if (selectedContacts.length > 0) { console.log('Delete contact IDs:', selectedContacts); } }; const handleDeleteLeadClick = () => { if (selectedLeads.length > 0) { console.log('Delete lead IDs:', selectedLeads); } }; return ( <> <MyAppBar /> <Container maxWidth="xl" sx={{ marginBottom: '4rem' }}> <Box sx={{ display: 'flex', width: '100%', justifyContent: 'center', marginTop: '5rem' }}> <Typography variant="h5" sx={{ marginY: '2rem' }}> Daftar Kontak </Typography> </Box> <Box sx={{ height: 400, width: '100%', mb: '2rem' }}> <DataGrid rows={contacts.map((contact, index) => ({ id: index + 1, ...contact }))} columns={contactColumns} pageSize={5} rowsPerPageOptions={[5, 10, 25, 50, 100]} checkboxSelection onSelectionModelChange={handleContactSelectionChange} /> </Box> <Stack direction="row" spacing={2}> <Button sx={{ textTransform: 'none' }} variant="outlined" component={Link} to="/add_contact"> <AddIcon /> Kontak Baru </Button> <Button sx={{ textTransform: 'none' }} variant="outlined" disabled={selectedContacts.length !== 1} onClick={handleEditContactClick} > <EditIcon /> Edit Kontak </Button> <Button sx={{ textTransform: 'none' }} variant="outlined" color="error" disabled={selectedContacts.length === 0} onClick={handleDeleteContactClick} > <RemoveCircleOutlineIcon /> Hapus Kontak </Button> <Button sx={{ textTransform: 'none' }} variant="outlined" href="#"> <FormatListNumberedRtlOutlinedIcon /> Lihat Semua </Button> </Stack> <Box sx={{ display: 'flex', width: '100%', justifyContent: 'center', marginTop: '6rem' }}> <Typography variant="h5" sx={{ marginY: '2rem' }}> Daftar Lead </Typography> </Box> <Box sx={{ height: 400, width: '100%', mb: '2rem' }}> <DataGrid rows={leads.map((lead, index) => ({ id: index + 1, ...lead }))} columns={leadColumns} pageSize={5} rowsPerPageOptions={[5]} checkboxSelection // 绑定Lead的选中事件 onSelectionModelChange={handleLeadSelectionChange} /> </Box> <Stack direction="row" spacing={2}> <Button sx={{ textTransform: 'none' }} variant="outlined" component={Link} to="/add_lead"> <AddIcon /> Lead Baru </Button> <Button sx={{ textTransform: 'none' }} variant="outlined" disabled={selectedLeads.length !== 1} onClick={handleEditLeadClick} > <EditIcon /> Edit Lead </Button> <Button sx={{ textTransform: 'none' }} variant="outlined" color="error" disabled={selectedLeads.length === 0} onClick={handleDeleteLeadClick} > <RemoveCircleOutlineIcon /> Hapus Lead </Button> <Button sx={{ textTransform: 'none' }} variant="outlined" href="#text-buttons"> <FormatListNumberedRtlOutlinedIcon /> Lihat Semua </Button> </Stack> </Container> </> ); }; export default Dashboard;
内容的提问来源于stack exchange,提问作者luthfinzo
相关产品推荐
相关产品推荐

