Reputation: 180
I've been scratching my head at this one for a while, I'm wondering why my state won't update. I have written a functional component and I know I'm missing something small but I don't know what.
The goal is to update an array containing the names of boxes which are checked (updated from an input checkbox). Here is the code I have
export default function Projects(props) {
const [checkedBoxes, setCheckedBoxes] = useState([]);
const onCheck = box => {
let boxes = [...checkedBoxes];
console.log(`Checking box ${box}`);
if (document.getElementById(box).checked) {
console.log(`Box checked`);
//Add box
boxes.push(box);
} else {
console.log(`Removing box`)
//Remove box
let index = 0;
for (let i = 0; i < boxes.length; i++) {
if (boxes[i] === box)
index = i;
}
boxes.splice(index, 1)
}
console.log(`Boxes is now ${boxes}`)
setCheckedBoxes(boxes);
console.log(`Checked boxes is now: ${checkedBoxes}`)
console.log(`Boxes length: ${boxes.length}`)
console.log(`Checked boxes length: ${checkedBoxes.length}`)
}
The console.log output is as follows:
Checking box box1
Box checked
Boxes is now box1
Checked boxes is now:
Boxes length: 1
Checked boxes length: 0
Can anybody provide any insight as to why this is happening (or give me a better idea on how to store this information?). The goal is to have users check boxes and then filter a different state (a list of projects), depending on the boxes checked.
Thank you
Upvotes: 1
Views: 1038
Reputation: 203457
React state updates are asynchronous, so trying to log the new state right after setting it will only log the current state. You can use an effect to log the state after it updates. Remember to add checkedBoxes
to the dependency array so the effect's callback is only invoked when it updates.
export default function Projects(props) {
const [checkedBoxes, setCheckedBoxes] = useState([]);
useEffect(() => {
console.log(`Checked boxes is now: ${checkedBoxes}`)
console.log(`Checked boxes length: ${checkedBoxes.length}`)
}, [checkedBoxes]);
const onCheck = box => {
let boxes = [...checkedBoxes];
console.log(`Checking box ${box}`);
if (document.getElementById(box).checked) {
console.log(`Box checked`);
//Add box
boxes.push(box);
} else {
console.log(`Removing box`)
//Remove box
let index = 0;
for (let i = 0; i < boxes.length; i++) {
if (boxes[i] === box)
index = i;
}
boxes.splice(index, 1)
}
console.log(`Boxes is now ${boxes}`)
console.log(`Boxes length: ${boxes.length}`)
setCheckedBoxes(boxes);
}
Upvotes: 5