-1

I'm trying to add items to an array saved as a local state (using useState) through a function that is sent to another screen as a navigation param.

Assume i have ScreenA which looks:

      ScreenA = () => {
        const[obj,setObj] = useState({arr:[]})
        
        addItem(item:any)=>{
        setObj([...obj,arr:arr.concat(item)])
        }
        
        const objContext = {
        obj,
        addItem
        }
        
        return(
        <objContext.Provider = value = {objContext}>
        <ScreenB/>
        <objContext/>
        )
        ///
        ...
        ///
        }
      screenB = () => {
        const {addItem} = useContext(Context)
        
        return(
        <View>
        <Button onPress{()=>navigation.navigate("ScreenC",{addItemFunc:addItem})} 
        </Button>
        </View>
        )}
        
    ScreenC = () => {
        return(
        <View>
        <Button onPress={()=>route.params.addItemFunc(1)}/>
        </View>
        )}
    export const Context = Tract.createContext({
    obj: {},
    addItem: (item: any) => null})

however while debugging, items are not getting added to the array, and only the last element added before returning to ScreenA is really added to the array.

menash
  • 13
  • 4

1 Answers1

1

Since you are passing in a reference as a callback function through your navigation params, you are possibly encountering a stale closure around obj within addItem. In otherwords, everytime you call that function, obj will be an empty array, as you initially defined it.

also noticed your initial state and addItem do not match up in terms of json structure. I will assume you want only an array with items (your initial state is an object which contains an array of items)

const[obj,setObj] = useState([])

Try using a callback function within the addItem function in order to get the latest state when calling addItem, in order to spread the correctly populated array.

  addItem(item:any)  =>  {
        setObj(prevObjState => [...prevObjState, item])
  }

if you want an object which contains an array

  const [item, addItem] = React.useState({arr:[]});
  

  const addAnotherItem = (item) => {
    addItem(prevState => ({...prevState, arr: [...prevState.arr, item] }))
  }
Gandzal
  • 1,217
  • 1
  • 3
  • 9