Home > Back-end >  React Native screen does not update when object state changes
React Native screen does not update when object state changes

Time:10-08

I am using react-native to build my app.

The main screen stores an object in the state:

const [menu, setMenu] = React.useState({name: "Pizza", toppings: {chicken: 2}})

and I display this state to the user as:

<Text>Qty: {menu.toppings.chicken}</Text>

I have a counter to update the state the loaginc to update the state is:

const handleChange = (action: string) => {
    if (action === 'add') {
      setMenu((prev) => {
        prev.toppings.chicken  = 1
        return prev
      })
    } else if (action === 'subtract') {
      setMenu((prev) => {
        prev.calendar.booking -= 1
        return prev
      })
    }
}

My function works correctly and changes the state to according to my needs(verified by console logging). However these changes are not reflexted in the <Text> where I am showing the quantity.

CodePudding user response:

You should research more about Shallow compare:

How does shallow compare work in react

In your case, you can try this code:

const handleChange = (action: string) => {
        if (action === 'add') {
            setMenu((prev: any) => {
                prev.toppings.chicken  = 1;
                return { ...prev };
            });
        } else if (action === 'subtract') {
            setMenu((prev: any) => {
                prev.calendar.booking -= 1;
                return {...prev};
            });
        }
    };

CodePudding user response:

This is your solution, it gets complicated with nested objects :

  const handleChange = () => {
setMenu((prevState) => ({
  ...prevState,
  toppings: { chicken: prevState.toppings.chicken   1 }
}));

};

CodePudding user response:

Hope This Solution Help:

import React from 'react';
import {View, Text, TouchableOpacity} from 'react-native';

export default App = () => {
  
const [menu, setMenu] = React.useState({
    name: 'Pizza',
    toppings: {
      value: 2,
    },
  });

  React.useEffect(() => {
    console.log('menu', menu);
  }, [menu]);

  const handleIncrement = () => {
    setMenu(prev => ({
      ...prev,
      toppings: {...prev.toppings, value: prev.toppings.value   1},
    }));
  };

  const handleDecrement = () => {
    setMenu(prev => ({
      ...prev,
      toppings: {...prev.toppings, value: prev.toppings.value - 1},
    }));
  };

  return (
    <View style={{flex: 1}}>
      <View
        style={{
          alignItems: 'center',
          flex: 1,
          flexDirection: 'row',
          justifyContent: 'space-evenly',
        }}>
        <TouchableOpacity onPress={handleDecrement}>
          <Text style={{fontSize: 44}}>-</Text>
        </TouchableOpacity>

        <Text>{menu.toppings.value}</Text>

        <TouchableOpacity onPress={handleIncrement}>
          <Text style={{fontSize: 44}}> </Text>
        </TouchableOpacity>
      </View>
    </View>
  );
};
  • Related