0

Hello I'm creating a table with .map this is how it looks:

enter image description here

I'm experimenting with checkbox I want to send all that data to another piece of code I'm working on did a few attempts with input type = 'checkbox' and failed and saw a few tutorials with Material UI Checkbox and decided to use that one cause it seems more reliable.

Now my question is: How can I check the checkbox individually, when I check on one it checks all of them. I know I'm sending the right parameters because the data I'm getting is the correct one, Example:

enter image description here

The UID is correct, it was false which means is correct (because code is not working yet) and finally is the first one (index 0) which means is grabbing all the right parameters, this is how it looks in the database you can see is grabbing the right UID, etc.

enter image description here

If I remove the conditions of my code it also does work, here how it looks (I clicked on both): enter image description here

The point of my code is to grab the students ID and put them on arrays so I can display them in another piece of code in a map, but for that I need the checkbox to work so that they add students to the Array when is check and to remove that student when is uncheck. I had to explain the whole thing so it makes sense what I'm trying to do, sorry if I took too long to make the question.

All I need is to understand how to make the checkbox works separately, the map array is making it too confusing.

This are the pieces of codes:

//Relevant Function + Variables.

const [studentID, setStudentID] = useState([])
const [ checked, setChecked ] = useState(false)

const setStudent = (estudiante, check, index) => {
  setChecked(prevState => !prevState);
  var checkBox = document.getElementById('checkBox');
     
  if(checkBox.ariaChecked === true){
         let data = studentID;
         data.push(estudiante);
         setStudentID(data);
         console.log("Hi I'm True")
         console.log(estudiante, check, index)
      }  
       else if (checkBox.ariaChecked === false){
        console.log("Hi I'm False")
           console.log(estudiante, check, index)
        }  
}

//Map
<tbody>
   {estudiantes.map((estudiante, index) => (
      <tr>
      
      <td>
      <Checkbox
      checked={checked}
      color = "primary"
      id = "checkBox"
      onChange = {() => setStudent(estudiante.uid, checked, index)}
      inputProps={{ 'aria-label': 'controlled' }}
      />
      </td>

      <td>{estudiante.name}</td>
      <td>{estudiante.school}</td>
      <td>{estudiante.grade}</td>

      <td>
      <Button 
       startIcon = {<DeleteIcon />}
       size = "medium"
       variant = "contained"
       color = "secondary"
       onClick = { ()=>{deleteProduct(estudiante.uid)}}>
       Borrar
       </Button>
       </td>

       </tr>
   ))}
</tbody>

ReactPotato
  • 1,262
  • 3
  • 26
  • 46

2 Answers2

1

Since you have an array of data where you are pushing the "estudiante.uid". You can use this array as condition. For example to check the checkbox when a student is added and unchecked when is deleted. I can see you have that data in the state, so:

const [studentID, setStudentID] = useState([])

const setStudent = (estudiante, index) => {     
if(!studentID.find(id => id === estudiante){
     setStudentID([ ... studentID, estudiante]); // adds a student id
     // let data = studentID; //This can go
     // data.push(estudiante); //This can go 
     console.log("Hi I'm True")
     console.log(estudiante, check, index)
  }  
   else {
    setStudentID(studentID.filter(studentId => studentId !== estudiante)) 
    //deletes a student id
    console.log("Hi I'm False")
       console.log(estudiante, check, index)
    }  
}

//Map
<tbody>
  {estudiantes.map((estudiante, index) => (
  <tr>
  
  <td>
  <Checkbox
  checked={studentID.find( id => id === estudiante.uid)}
  color = "primary"
  id = "checkBox"
  onChange = {() => setStudent(estudiante.uid, index)}
  inputProps={{ 'aria-label': 'controlled' }}
  />
  </td>

  <td>{estudiante.name}</td>
  <td>{estudiante.school}</td>
  <td>{estudiante.grade}</td>

  <td>
  <Button 
   startIcon = {<DeleteIcon />}
   size = "medium"
   variant = "contained"
   color = "secondary"
   onClick = { ()=>{deleteProduct(estudiante.uid)}}>
   Borrar
   </Button>
   </td>

   </tr>
   ))}
 </tbody>
Julio Lopez
  • 1,107
  • 1
  • 9
  • 17
  • I'm having issues with `if(studentID.find(id => id === estudiante))` the condition is never met. Also I get an error when I use `setStudentID([ ...data, estudiante]);` and lastly why should I remove the `let data = studentID;` won't I be missing `data` to make it work with `setStudentID([ ...data, estudiante]);` ? – ReactPotato Sep 22 '21 at 12:59
  • 1
    Yes I forgot to change that data variable there. It should be the studentID array instead. I updated the answer. Also the condition changed – Julio Lopez Sep 22 '21 at 13:21
  • Is kind of working but I'm getting this error: `Material-UI: A component is changing the uncontrolled checked state of SwitchBase to be controlled. Elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled SwitchBase element for the lifetime of the component. The nature of the state is determined during the first render, it's considered controlled if the value is not "undefined"` – ReactPotato Sep 22 '21 at 13:52
  • 1
    That could be because the find() is undefined when it doesn't find something. So, in the checked attribute you can do checked={!!studentID.find( id => id === estudiante.uid)}. With double !! to convert the undefined in false – Julio Lopez Sep 22 '21 at 13:57
  • Oh that worked I didn't even knew you could do this -> !! thank you very much do you have a documentation about that so I can read it ? – ReactPotato Sep 22 '21 at 14:12
  • 1
    https://stackoverflow.com/a/10467486/8151873 – Julio Lopez Sep 22 '21 at 14:37
0

Ok thats the point, you created checked state as a boolean, that means that all the elements of the mapped array will inherit that boolean state, so when the state changes to true, all the elements will have the checked state set to true. If you want to deal with multiple checkbox you should have to initialize the checked state as an array with the same number of elements as the estudiantes array as you did with studentId.

This post explains it well https://www.freecodecamp.org/news/how-to-work-with-multiple-checkboxes-in-react/

Nacho
  • 870
  • 6
  • 9