React Enjoyer
React Enjoyer

Reputation: 1402

Why there's a update state delay in checkbox, React

Something very weird is going on with my code and it does not makes any sense. Every time I save/store some data it has a "delay" like for example if I click 2 checkboxes, when I click the first one nothing happens, when I click the second one it grabs the value of the first one I clicked. let me show you:

enter image description here

Now the same happens when I click the one that selects all of them but it does not affects the maths at least (which is the most important part) here:

enter image description here

if I unselect all it shows that all the values where being saved at least:

enter image description here

now comes the even more weird part if I do one by one then the maths doesn't match and is because is not "adding" the one I click first:

enter image description here

Here is my piece of code I mean technically is working but clearly I'm missing something idk let me know if you require something else:


// "librosnuevos" get updated on the firebase I will not add it cause I think is not necessary 

const [librosNuevos, setLibrosNuevos] = useState([]);
const [LibrosID, setLibrosID] = useState([]);
    const handleChange = (e, data) => {
    const { name, checked } = e.target;
    if (checked) {
      // if cheked and selectall checkbox add all fileds to selectedList
      if (name === "allSelect") {

        setLibrosID(librosNuevos);
        let x = 0
        librosNuevos.map((i) => {
          x += i.precio
          setTPLibrosNuevos(parseFloat(x).toFixed(2))
        })

      } else {
        // if cheked and specific checkbox add specific field to selectedList
        setLibrosID([...LibrosID, data]);

        let x = 0
        LibrosID.map((i) => {
          x += i.precio
          setTPLibrosNuevos(parseFloat(x).toFixed(2))
        })
      }
    } else {
      // if uncheked and selectall checkbox add remove all fileds from selectedList
      if (name === "allSelect") {
        setLibrosID([]);

        let x = 0
        librosNuevos.map((i) => {
          x = 0
          setTPLibrosNuevos(parseFloat(x).toFixed(2))
        })

      } else {
        // if uncheked and specific checkbox remove specific field from selectedList
        let tempuser = LibrosID.filter((item) => item.id !== data.id);
        setLibrosID(tempuser);

        let x = 0
        tempuser.map((i) => {
          x += i.precio
          setTPLibrosNuevos(parseFloat(x).toFixed(2))
        })
      }
    }
    console.log(LibrosID)
  };

//Parent Checkbox
<input
type="checkbox"
className="form-check-input"
name="allSelect"
checked={LibrosID?.length === librosNuevos?.length}
onChange={(e) => handleChange(e, librosNuevos)}
/>

//Mapped checkbox-child

{librosNuevos.map((libros, index) => (
<tr key={libros.id || index}>
<td >
<input
type="checkbox"
className="form-check-input"
 name={libros.id}
checked={LibrosID.some((item) => item?.id === libros.id)}
onChange={(e) => handleChange(e, libros)}
/>

... some smart code that finish the table
}

Gifs requested:

Gif 1 Gif 2

This is what I get after trying that answer:

enter image description here

is half working now which is still an upgrade, still need to make the prices add up correctly this is what I tried:

 useEffect(() => {
    console.log(LibrosID);
 }, [LibrosID])

 useEffect(() => {
  console.log(tpLibrosNuevos);
}, [tpLibrosNuevos])

tpLibrosNuevos is the total price that it should update every time I select an option but it only does it after the first one. Maybe my maths are wrong somewhere? I doubled checked and doesn't seem to be the case...

Upvotes: 0

Views: 1936

Answers (1)

tomleb
tomleb

Reputation: 2525

This is not necessarily a delay. setState is an async function, meaning that, since you log to console right after setting the state, you can't be sure that it has finished.

You can check your state using a useEffect that has state as a dependency.

Like this:

useEffect(() => {
   console.log(LibrosID, librosNuevos);
}, [LibrosID, librosNuevos])

This is a callback that will, by definition, run only after the LibrosID or librosNuevos have been changed.

You can read more about this here

Upvotes: 2

Related Questions