So i created a app takes attendance of students. but when i try to check out useEffect resets the state of numStudents after update.
the code is :
const Attendance = () => {
// Declare state variables
const [students, setStudents] = useState([]);
const [numStudents, setNumStudents] = useState(0);
// Function to add a student to the attendance list
const addStudent = (rollNumber, name) => {
setStudents(
students.concat({
rollNumber,
name,
checkInTime: new Date().toLocaleString(),
})
);
};
// Function to check a student out
const checkOut = (rollNumber) => {
setStudents(
students.map((student) => {
if (student.rollNumber === rollNumber) {
return { ...student, checkOutTime: new Date().toLocaleString() };
}
return student;
})
);
setNumStudents(students.length-1);
};
// Use effect hook to update the number of students when the 'students' state variable changes
useEffect(() => {
setNumStudents(students.length);
}, [students]);
return (
<div>
{/* Form to input student roll number and name */}
<form
onSubmit={(e) => {
e.preventDefault();
addStudent(e.target.rollNumber.value, e.target.name.value);
e.target.rollNumber.value = "";
e.target.name.value = "";
}}
>
<div className="container">
<h1>Student Attendance</h1>
<label>
Roll Number
<input type="number" name="rollNumber" />
</label>
<br />
<label>
Name
<input type="text" name="name" />
</label>
<br />
<button type="submit">Check In</button>
</div>
</form>
{/* Display number of students present */}
<p>There are currently {numStudents} students in the school.</p>
{/* Table to display list of students and their check in/out times */}
<br />
<table className="fl-table">
<thead>
<tr>
<th>Roll Number</th>
<th>Name</th>
<th>Check In Time</th>
<th>Check Out Time</th>
</tr>
</thead>
<tbody>
{students.map((student) => (
<tr key={student.rollNumber}>
<td>{student.rollNumber}</td>
<td>{student.name}</td>
<td>{student.checkInTime.toString()}</td>
<td>
{student.checkOutTime ? (student.checkOutTime.toString()) : (
<button
key={student.rollNumber} onClick={() => checkOut(student.rollNumber)}>
Check Out
</button>
)}
</td>
</tr>
))}
</tbody>
</table>
</div>
);
};
export default Attendance;
i tried using setNumStudents(students.length-1) in checkOut function but it updates and then useEffect is called that resets it again . How do i make it not reset ? i am new to react Hooks so plz help!!!
CodePudding user response:
Why do you need an effect here at all? I mean you already updating numStudents in checkout handler. Ideally useEffect should be used to hook up your app to external library or make a http request(like fetching students from server)
When you checkout student you responding to event fired by user, and should update state variables in event handler.
// Function to add a student to the attendance list
const addStudent = (rollNumber, name) => {
setStudents(
students.concat({
rollNumber,
name,
checkInTime: new Date().toLocaleString(),
})
);
setNumStudents(numStudents 1)
};
// Function to check a student out
const checkOut = (rollNumber) => {
setStudents(
students.map((student) => {
if (student.rollNumber === rollNumber) {
return { ...student, checkOutTime: new Date().toLocaleString() };
}
return student;
})
);
setNumStudents(numStudents - 1);
};