Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
282 views
in Technique[技术] by (71.8m points)

react native - useState array not updated when invoking function from another screen

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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] }))
  }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...