Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
155
rated 0 times [  159] [ 4]  / answers: 1 / hits: 5488  / 4 Years ago, tue, january 7, 2020, 12:00:00

I am new to React and I am very confused about the lifecyle of a functional component.
Let's say I have many inputs of type: checkbox, a, b, c and d. Their values are a, b, c and d.





const OnBoarding = () => {
const [isChecked, setIsChecked] = useState({
a: false,
b: false,
c: false,
d: false
});

const [allCheckedItems, setAllCheckedItems] = useState([]);

//Write function that pushes checked value to state array when clicked
const onChecked = e => {
setIsChecked({
...isChecked,
[e.target.value]: e.target.checked
});
const all = Object.keys(isChecked).filter(function(key){
return isChecked[key] === true;
});
console.log(all items that are TRUE : + all);
setAllCheckedItems([all]);
console.log(allCheckedItems : + allCheckedItems);
};

useEffect(() => {
console.log(isChecked);
});

}

<script src=https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js></script>
<script src=https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js></script>





I have a functional component with a state whose type is an object with many properties, all booleans, like so:



const [isChecked, setIsChecked] = useState({
a: false,
b: false,
c: false,
d: false
})


I have an other state that is an array, let's call it allCheckedItems, that is supposed to be an array of all the keys of isChecked set to true.



const [allCheckedItems, setAllCheckedItems] = useState([]);


With a function onChecked, when a checkbox is checked, it's value in the isChecked object sets to true.



I call useEffect() in which I wrote a filter function to filter all properties that are true. All the properties set to true are store in an array called all.



My problem comes when I have to update the state of the array allCheckedItems. If I write in the useEffect hook:



setAllCheckedItems([all]);


I get an infinite loop. If I write it in my onChecked function, whenever I click on a checkbox, the state of allCheckedItems that I log in the console is LATE of one click.
Like, I click to check a and it logs:



[]


Then I click on b and it logs:



[a]


Then I click on c and it logs:



[a, b]


I would like that when I check a box, both states update and that allItemsChecked logs all items checked immediately...
Can someone explain to me this behavior? It has given me headaches for days now.


More From » reactjs

 Answers
4

The reason why the useEffect hook gives you an infinite loop is because useEffect is triggered after every render when it is not supplied with the second argument. This is stated on the official react documentation for react hooks, and that the component will skip the applying of the effect if the values within the second argument have not changed.



While calling setAllCheckedItems() within your useEffect() can work if we set [isChecked] as the second argument of useEffect() (which will ensure that the effect will only be applied if the values of isChecked has changed),



useEffect(() => {
setAllCheckedItems([all]);
}, [isChecked]);


I would recommend you to reduce the complexity of the code by simply calling setAllCheckedItems() at your onClick event of your checkbox, since it is to be run everytime the checkbox is checked. You can refactor the onChecked method such that setAllCheckedItems() is not reliant on the isChecked state.



const onChecked = (e) => {
// get current checked state, and update it with the checkbox values
const updatedChecked = {
...isChecked,
[e.target.value]: e.target.checked
}
// update isChecked state
setIsChecked(updatedChecked);
const all = Object.keys(updatedChecked).filter(function(key){
return updatedChecked[key] === true;
});
// update allCheckedItems state
setAllCheckedItems([all]);
}


As you can see, we have created a copy of the isChecked state, and update the copy with the new values. In addition, we use that copy to return the keys that are checked. After which, we update the respective states.


[#5127] Sunday, January 5, 2020, 4 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
aidan

Total Points: 72
Total Questions: 95
Total Answers: 121

Location: Uzbekistan
Member since Sat, Feb 27, 2021
3 Years ago
aidan questions
Mon, Oct 11, 21, 00:00, 3 Years ago
Wed, Sep 29, 21, 00:00, 3 Years ago
Sun, Sep 5, 21, 00:00, 3 Years ago
Thu, Jan 16, 20, 00:00, 4 Years ago
Thu, Sep 19, 19, 00:00, 5 Years ago
;