0

Alright I have a checkbox and when is checked it should save some value and when is unchecked it should delete the value of the one I just unchecked. From what I saw in Material UI: Checkbox there is an "easy way" in the "Controlled" section but it didn't work so I try something else but is not working neither aaand now I'm stuck. I saw a similar problem and tried that Stackoverflow: How to call 2 functions on onclick of a checkbox?. But apparently that didn't work neither because is from the regular checkbox but I want to use the checkbox from Material UI. This is what I have:

Relevant code

const [studentID, setStudentID] = useState([])
const setStudent = (estudiante) => {
  var checkBox = document.getElementById('checkBox');
     if(checkBox.ariaChecked == true){
         console.log("Save data")
         let data = studentID;
         data.push(estudiante);
         setStudentID(data);
         console.log(studentID)
      } 
       else{
         console.log("Delete data")
        }  
}

                <Checkbox  
                color = "primary"
                id = "checkBox"
                onChange = {() => setStudent(estudiante.uid)}
                inputProps={{ 'aria-label': 'controlled' }}
                />

I try to adapt it from previous suggestions I saw from other posts but it didn't work it only goes through one option (I haven't create the code to delete the value just added a console.log)

enter image description here

if I invert them this is how it looks when I try to save data (this does works but since it only does one or the other it repeats)

enter image description here

Any tips, suggestions, documentation or help is very well appreciate it. Let me know if require something else.

isherwood
  • 58,414
  • 16
  • 114
  • 157
ReactPotato
  • 1,262
  • 3
  • 26
  • 46

1 Answers1

1

Well, in the first place you need to control the state of the component. This means you have manage when it is checked and when it is not checked. For that you need to add an attribute "checked" to your component which is gonna be part of the state:

    const [ checked, setChecked ] = useState(false)

    <Checkbox  
      checked={checked}
      ...
    />

After this part is done. Now you have two options. You can do it the way you are trying to do it and the code would be something like this:

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

const setStudent = (estudiante, check) => {
  console.log(estudiante, check) //here you will probably have the inverted value of the check because you are getting the old state. But you can work with it 
  setChecked(prevState => !prevState);
     if(check){
         console.log("Save data")
         let data = studentID;
         data.push(estudiante);
         setStudentID(data);
         console.log(studentID)
      } 
       else{
         console.log("Delete data")
        }  
}

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

And the second option taking advantage of the useEffect hook:

    const [studentID, setStudentID] = useState([])
    const [ checked, setChecked ] = useState(false)
    const [ id, setId ] = useState(null)
    
    useEffect(() => {
       const setStudent = () => {
        if(checked){
          //your code
        }else{
          //your code
        }
       }
       // IMPORTANT: you need to remember that this useEffect is going to run once when the components just renders. So you need to put a condition here before calling the function 
       if(!isFirstTime){
          setStudent()
       }
    },[checked, id])

        <Checkbox  
          checked={checked}
          color = "primary"
          id = "checkBox"
          onChange = {() => {setId(estudiante.uid),setChecked(prevState => !prevState)}}
          inputProps={{ 'aria-label': 'controlled' }}
        />

UPDATE:

Since you told me the checkbox is inside of a map. You can use your data state to reflect the checked checkboxes for example:

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

// This is just an example code since I don't see all your code.
const setStudent = (estudiante) => {
  if (setStudentID.find(studentId => studentId === estudiante.uid)) {
    setStudentID([ ...data, estudiante])
    ... //your code
  }else{
    setStudentID(data.filter(studentId => studentId !== estudiante))
    ... //your code
  }
}

    <Checkbox  
      checked={setStudentID.find(studentId => studentId === estudiante.uid)}
      color = "primary"
      id = "checkBox"
      onChange = {() => setStudent(estudiante.uid)}
      inputProps={{ 'aria-label': 'controlled' }}
    />
Julio Lopez
  • 1,107
  • 1
  • 9
  • 17
  • This sure helps a lot, now I have to make it work on a map, cause when I check one all of them get checked but this helped a lot – ReactPotato Sep 22 '21 at 01:04
  • How do I make it only check 1 checkbox and not all of them :c ? – ReactPotato Sep 22 '21 at 01:18
  • 1
    Again there is many ways of doing this. I can't see all the code you have there. But I see you have an array of data where you are pushing the student Id. This array would be amazing if it is in the state (for that you shouldn't mutate "data.push)" but use concat and filter to add and delete elements. And this could be your "checked" condition. If the ID is there checked. If not unchecked. for example studentId === estudiante.uid) ...} />.. Again I hope this helps – Julio Lopez Sep 22 '21 at 05:25
  • I didn't want to pollute this post with more questions so I made a new question instead [check checkbox individually](https://stackoverflow.com/questions/69278573/how-to-check-checkbox-individually-in-a-map-array) it is also another question but is related! – ReactPotato Sep 22 '21 at 05:28
  • I just did edited the answer here. I hope that helps. Let me know – Julio Lopez Sep 22 '21 at 05:36