Массив useState не обновляется при вызове функции с другого экрана

#react-native #navigation #react-hooks #react-context #react-navigation-v5

#react-native #навигация #реагирующие перехваты #реагировать-контекст #react-navigation-v5

Вопрос:

Я пытаюсь добавить элементы в массив, сохраненный как локальное состояние (с использованием useState), с помощью функции, которая отправляется на другой экран в качестве параметра навигации.

Предположим, у меня есть ScreenA, который выглядит:

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

однако во время отладки элементы не добавляются в массив, и только последний элемент, добавленный перед возвратом в ScreenA, действительно добавляется в массив.

Ответ №1:

Поскольку вы передаете ссылку в качестве функции обратного вызова через свои параметры навигации, вы, возможно, сталкиваетесь с устаревшим закрытием obj внутри addItem . Другими словами, каждый раз, когда вы вызываете эту функцию, obj будет пустым массивом, как вы его изначально определили.

также заметил, что ваше начальное состояние и addItem не совпадают с точки зрения структуры json. Я предполагаю, что вам нужен только массив с элементами (ваше начальное состояние — это объект, который содержит массив элементов)

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

Попробуйте использовать функцию обратного вызова внутри функции addItem, чтобы получить последнее состояние при вызове addItem, чтобы распространить правильно заполненный массив.

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

если вам нужен объект, содержащий массив

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

  const addAnotherItem = (item) => {
    addItem(prevState => ({...prevState, arr: [...prevState.arr, item] }))
  }