I’m working on a React application where I have a table displaying student data fetched from an API. Each row in the table includes a checkbox to select the student for further processing. However, I’m facing an issue where clicking on one checkbox seems to automatically select another checkbox in a different row.
I implemented a React table component using Material-UI’s Checkbox to allow users to select students from a fetched list. Each row in the table represents a student with a checkbox for selection.
I expected that clicking on a checkbox would only select or deselect the student in the corresponding row without affecting other rows. This means each checkbox should operate independently of others.
import React, { useState, useEffect } from 'react';
import { Checkbox, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Button, Grid, Typography, Container } from '@mui/material';
import AddCircleOutlineIcon from '@mui/icons-material/AddCircleOutline';
import { makeStyles } from '@mui/styles';
import Navbar from '@/components/navbar';
const useStyles = makeStyles((theme) => ({
container: {
paddingTop: theme.spacing(8),
paddingBottom: theme.spacing(8),
color: theme.palette.text.primary,
},
form: {
maxWidth: 600,
margin: 'auto',
},
button: {
marginTop: theme.spacing(2),
},
tableContainer: {
marginTop: theme.spacing(4),
},
}));
export default function AdmitCardPage() {
const classes = useStyles();
const [students, setStudents] = useState([]);
const [selectedStudents, setSelectedStudents] = useState([]);
useEffect(() => {
fetchStudents();
}, []);
const fetchStudents = async () => {
try {
const response = await fetch('http://localhost:3002/students');
if (!response.ok) {
throw new Error('Failed to fetch students');
}
const data = await response.json();
setStudents(data);
} catch (error) {
console.error('Error fetching students:', error);
}
};
const handleSelectStudent = (student) => {
setSelectedStudents((prevSelectedStudents) => {
if (prevSelectedStudents.some((s) => s.id === student.id)) {
return prevSelectedStudents.filter((s) => s.id !== student.id);
} else {
return [...prevSelectedStudents, student];
}
});
};
const handleSave = () => {
console.table(selectedStudents);
// Replace with logic to save selected students
};
return (
<>
<Navbar />
<Container className={classes.container}>
<Typography variant="h4" align="center" gutterBottom>
Admit Card
</Typography>
<Grid container spacing={2} className={classes.form}>
<Grid item xs={12}>
<Button
variant="contained"
color="primary"
onClick={fetchStudents}
className={classes.button}
startIcon={<AddCircleOutlineIcon />}
>
Fetch Students
</Button>
</Grid>
</Grid>
<TableContainer className={classes.tableContainer}>
<Table>
<TableHead>
<TableRow>
<TableCell>Select</TableCell>
<TableCell>Student Name</TableCell>
{/* Add more headers as needed */}
</TableRow>
</TableHead>
<TableBody>
{students.map((student) => (
<TableRow key={student.id}>
<TableCell>
<Checkbox
checked={selectedStudents.some((s) => s.id === student.id)}
onChange={() => handleSelectStudent(student)}
color="primary"
/>
</TableCell>
<TableCell>{student.name}</TableCell>
{/* Add more cells as needed */}
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
<Button
variant="contained"
color="secondary"
onClick={handleSave}
className={classes.button}
>
Save Selected Students
</Button>
</Container>
</>
);
}