Home > Blockchain >  useEffect resets the numStudents state after check out
useEffect resets the numStudents state after check out

Time:01-05

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);
  };
  • Related