I am trying to add values to a useState hook as a checkbox is clicked and remove that value when unchecked. I can add the values just fine but I can’t seem to figure out how to remove them. I can get this process to work for the price useState which is a float, but doing this action on a string is where I run into issues.
Here is the code section:
const [price, setPrice] = useState(0.00);
const [specOrder, setSpecOrder] = useState("");
const [specBurgers, setSpecBurgers] = useState([]);
useEffect( () => {
axios.get('http://localhost:8800/specialtyburgers')
.then(res => {
setSpecBurgers(res.data);
})
}, [])
function handleSpec(p, e) {
var temp = parseFloat(p);
if(e.target.checked) {
setSpecOrder(prevSpecOrder => prevSpecOrder + e.target.value);
setPrice(prevPrice => prevPrice + temp);
}
else if(!e.target.unchecked){
setSpecOrder(prevSpecOrder => prevSpecOrder);
setPrice(prevPrice => prevPrice - temp);
}
}
var specBurgerDetails = "";
specBurgerDetails = specBurgers.map( (item, index) => {
return(
<div className="item">
<h2 key={index} className='itemName'>{item.SpecBurgerType}</h2>
<p>{item.Protein}</p>
<p>{item.Toppings}</p>
<p>{item.Price}</p>
<input type='checkbox' value={item.SpecBurgerType} onChange={(e) => handleSpec(item.Price, e)}/>
<p>{specOrder}</p>
<p>{price}</p>
</div>
)
});
3
Answers
I’d suggest making the state of the checkbox part of your state and making the total price a calculated value rather than a value stored in state.
I don’t know what "spec order" is supposed to be in your code and there isn’t enough detail to show doing the above in the context of your code, but here’s an example of having a price and, separately, an extra amount that is conditionally included in the total:
It might make more sense to calculate your specOrder variable and price on each render, rather than storing them in state. See the below example – the only state you need to store is the checkbox state, and then you can build the value you need. Trying to keep it in sync will invariably lead to headaches. See the example below: it’s a bit contrived and you could abstract some of it into reusable hooks/components but it illustrates the point.
If you still want to use state, you can copy use the
usePrevious
hook that’s available in other codebases. EG: https://github.com/streamich/react-use/blob/master/src/usePrevious.tsThe event triggered when checking contains the value of the element that is being checked or unchecked. Just add it and subtract when necessary to the previous state that you have. The which in this case for example I am getting from the setState’s callback function. It’s also good to know that the event returns a string, so we just turn it into a number with
Number()