Home > Enterprise >  React Native: Counter not showing correct updated state
React Native: Counter not showing correct updated state

Time:05-25

Im trying to put together a simple counter which changes the quantity of an item. Using Hooks to manage its state, i update the value on screen correctly. However, the value the state holds when i console log is always one less than the value on the screen.

For example:

If starting value is 1, after pressing the plus button, the value on screen changes to 2 but in console the state value is still 1.

Setup of Hooks and functions controlling the count:

//Set Quantity
const [quantity, setQuantity] = useState(1);

//Set Item price
const [itemPrice, setItemPrice] = useState(itemOptions[0].price)

//Counter Control
 const [disableMinus, setDisableMinus] = useState(true);

const addQuantity = () => {
    if (quantity === 1) {
        setQuantity(quantity   1);
        setDisableMinus(false);
        console.log(quantity)
    } else {
        if (quantity > 1){
            setQuantity(quantity   1);
            setDisableMinus(false);
            console.log(quantity)
        }
    }
}
const minusQuantity = () => {
   if (quantity === 1){
       setDisableMinus(true);
   } else {
       if (quantity > 1) {
           setQuantity(quantity - 1);
           setDisableMinus(false);
           console.log(quantity)
       }
   }
} 

return (
    <View style={{flexDirection: 'row', alignItems: 'center', justifyContent: "center", paddingVertical: 20}}>

    <TouchableOpacity disabled={disableMinus} onPress={() => minusQuantity()}>

        <AntDesign style={{color: '#37BD6B'}} name="minuscircle" size={30}/>

    </TouchableOpacity>

    <Text style={{paddingHorizontal: 10, fontWeight: '700', fontSize: 30}}>{quantity}</Text>

    <TouchableOpacity onPress={() => addQuantity()}>

        <AntDesign style={{color: '#37BD6B'}} name="pluscircle" size={30}/>

    </TouchableOpacity>
)

Thanks in advance

CodePudding user response:

Setters from useState are async.

You could log it this way

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

This means: when dependency [quantity] change, execute the function passed as first param

To avoid stale closure (happening when 2 fast clicks or rand randers), you should use setters and passing it a function instead of the "current" value:

setQuantity(prevQuantity => prevQuantity   1);

CodePudding user response:

Here is another way you might set things up:


const addQuantity = () => {
  ...
      setQuantity(oldQuantity => {
        const newQuantity = oldQuantity   1
        console.log(newQuantity) // console.log moved here. Also could be console.log("Incremented quantity to:", quantity)
        return newQantity
      });
  ...
}

This approach would allow you to log the new quantity value beore it is set. In this approach, you can perform a specific action (in this case console.log) on a case by case basis.

On the other hand, the useEffect approach in @Poptocrack's answer will track all changes to the quantity state. It has significantly less code and could be more desirable depending on your needs.

Hope you find one that fits your needs best from the two approaches.

  • Related