1

I am currently trying to assign state to a nested object using the hook setState() but I'm struggling a little bit with figuring out the syntax and how exactly I am supposed to do it.

I have structured my component like this:

const MainCard = props =>{

       const passedState = props.location.state;

     return(
          <div className="main-container">
             <div className="row">
               <div className="col-md-6 col-lg-6">
                    <AttendeeCard passedState={passedState} />
               </div>
               <div className="col-md-6 col-lg-6">
                    <AttendeeCard passedState={passedState} />
               </div>
             </div>
          </div>
   )
}

export default withRouter(MainCard)

So the props received from location are the data that I'll be passing to the AttendeeCard component.

Here is the data I'm passing down the component.

I have structured my AttendeeCard component the following way:

  const AttendeeCard = props =>{

            const students= props.passedState.students;
            const [isChecked, setIsChecked] = useState(false);

            const checkInStudent= () =>{
               setIsChecked(!isChecked);
            }


        return(
             students.map((student,i)=>{
                 return(
                      <div className="studentCard">
                          <div className="checkinput">
                              <input type="checkbox" 
                                  onChange={checkInStudent}
                                  checked value={isChecked}/>
                               <span className="slider round"></span>
                          </div>
                      </div>
                  )
             })

     )
   }

So instead of using const [isChecked, setIsChecked] = useState(false); to assign one state to all checkboxes, I'd like to assign each checkedin state corresponding to the users.

I've tried writing something like:

       students.map((student,i)=>{
             const [isChecked, setIsChecked] = useState(student.checkedin);

           return(
                      <div className="studentCard">
                          <div className="checkinput">
                              <input type="checkbox" 
                                  onChange={checkInStudent}
                                  checked value={isChecked}/>
                               <span className="slider round"></span>
                          </div>
                      </div>
                  )
             })
       })

but I got an error and it didn't compile.

How can I assign state for each of the checkedin nested objects per student in my array?

UPDATE:

The error I get whenever I try the code above is:

React Hook "useState" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function react-hooks/rules-of-hooks

2 Answers 2

1

One of the rules of React hooks is don't call hooks inside loops. You can instead move your code into a new component and call the hook inside the component:

function StudentCard({ checkedIn }) {
  const [isChecked, setIsChecked] = useState(checkedIn);
  const checkInStudent = () => {
    setIsChecked(!isChecked);
  };

  return (
    <div className="studentCard">
      <div className="checkinput">
        <input
          type="checkbox"
          onChange={checkInStudent}
          checked
          value={isChecked}
        />
        <span className="slider round"></span>
      </div>
    </div>
  );;
}

const AttendeeCard = props => {
  const students = props.passedState.students;

  return students.map((student, i) => {
    return (
      <StudentCard
        checkedIn={student.checkedin}
        key={i}
      />
    );
  });
};

Sign up to request clarification or add additional context in comments.

Comments

0

I think you can make your code work by creating a new child component for the studentCard. So your code would be something like this :

const AttendeeCard = props =>{
    const students= props.passedState.students;

    return(
         students.map((student,i)=>{
             return(
                  <StudentCard student=student/>
              )
         })

 )

}

and StudentCard would be like this:

const StudentCard = props =>{
       const [isChecked, setIsChecked] = useState(props.student.checkedin);

       return(
                  <div className="studentCard">
                      <div className="checkinput">
                          <input type="checkbox" 
                              onChange={checkInStudent}
                              checked value={isChecked}/>
                           <span className="slider round"></span>
                      </div>
                  </div>
              )
}

By this way every StudentCard has it internal state and you can change it every time you want.

I hope it solves your problem. If it works please vote me up:)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.