React Native 如何获取已由扩展运算符更新的有状态数组的最后一个值?
Posted
技术标签:
【中文标题】React Native 如何获取已由扩展运算符更新的有状态数组的最后一个值?【英文标题】:React Native how can I get last value of stateful array which has been updated by a spread operator? 【发布时间】:2022-01-16 06:46:29 【问题描述】:我正在更新一个列表(有点像待办事项列表)并尝试将其保存到 AsyncStorage,但添加到数组中的最新项目总是丢失。为什么?
这是有问题的函数(为了澄清而缩短):
// At beginning of component
let [itemsArray, updateItemsArray] = useState([])
const addItem = async (item) =>
const currentItem =
id: uuid(), // <-- temporary way of getting key for now
name: item.name
// Use spread operator to update stateful array for screen listing
// The listing on the screen updates perfectly with the 'new item' in place at the bottom
of a list
updateJobsArray(prevItems => [...prevItems, currentJob])
// Now, stringify the items array in preparation for saving to AsyncStorage
updateItemsArray(prevItems => [...prevItems, currentItem])
try
const jsonValue = JSON.stringify(itemsArray)
await AsyncStorage.setItem('items', jsonValue)
catch (e)
Alert.alert('Error', 'Something went horribly, irrevocably... wrong')
当我 console.log AsyncStorage.getItem('items') 时,最后添加的项目总是从项目的结果列表中丢失。项目列表总是缺少最后添加的项目。我认为问题在于扩展运算符更新有状态的“itemsArray”的方式。就好像状态更新是异步的,对 AsyncStorage 的写入发生在更新完成之前,但我不知道为什么,请帮助...
【问题讨论】:
【参考方案1】:我重现了工作示例的问题,请在https://snack.expo.dev/@emmbyiringiro/c65dbb 测试代码
import * as React from 'react';
import Text, View, StyleSheet,Button,AsyncStorage,Alert,ScrollView from 'react-native';
import Constants from 'expo-constants';
import faker from 'faker'
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import Card from 'react-native-paper';
export default function App()
let [itemsArray, updateItemsArray] = React.useState([])
let [savedUsers, updateSavedUsers] = React.useState([])
let [asyncOps,updateAsyncOps] = React.useState(saveStatus:"undetermined",retrieveStatus:"undetermined")
const save = async ()=>
const newUser =
id:faker.datatype.uuid()
,
name: faker.name.findName(), // Rowan Nikolaus
email: faker.internet.email(),// Kassandra.Haley@erich.biz,
phone:faker.phone.phoneNumber(),
const tempUsers = [...itemsArray,newUser]
const serializeValues = JSON.stringify(itemsArray)
try
updateAsyncOps(...asyncOps,saveStatus:"pending")
await AsyncStorage.setItem('users', serializeValues)
await retrieve()
updateItemsArray(tempUsers)
updateAsyncOps(...asyncOps,saveStatus:"succeeded")
catch (e)
updateAsyncOps(...asyncOps,saveStatus:"failed")
Alert.alert('Error', 'Something went horribly, irrevocably... wrong')
const retrieve = async () =>
try
updateAsyncOps(...asyncOps,retrieveStatus:"pending")
const value = await AsyncStorage.getItem('users');
if (value !== null)
// We have data!!
console.log(value);
const deSerializeValue = JSON.parse(value)
updateSavedUsers( deSerializeValue)
updateAsyncOps(...asyncOps,retrieveStatus:"suceeded")
catch (error)
// Error retrieving data
Alert.alert('Error', 'Something went horribly, irrevocably... wrong')
updateAsyncOps(...asyncOps,retrieveStatus:"failed")
;
return (
<ScrollView style=styles.container>
<Card>
<View>
savedUsers.map(user=>
return (
<View style=paddingVertical:5 key=user.id>
<Text> user.name </Text>
<Text> user.email </Text>
<Text> user.phone </Text>
</View>
)
)
</View>
<View style=padding:10>
<Button onPress=save title ='Add User ' disabled=asyncOps.saveStatus === 'pending'/>
<View style=paddingVertical:10>
<Button onPress=retrieve title ='Retrieve Users ' disabled=asyncOps.retrieveStatus === 'pending'/>
</View>
</View>
</Card>
</ScrollView>
);
const styles = StyleSheet.create(
container:
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
,
paragraph:
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
,
);
【讨论】:
请不要只发布链接。请使用回答问题的相关代码进行编辑。答案和问题不应依赖外部资源。 @DᴀʀᴛʜVᴀᴅᴇʀ,该链接是开发环境中的解决方案。问题作者可以查看解决方案并测试代码。 答案应该仍然有回答问题的相关部分。可以链接到完整的运行环境,但回答问题的所有相关方面都应该在答案中。这可以防止链接失效。 好的。感谢您的澄清。我在这里添加了解决方案代码。 这是一个非常全面的答案。我实际上编写了一个解决方法,但这段代码看起来更接近我想要的。谢谢@BYIRINGIRO Emmanual以上是关于React Native 如何获取已由扩展运算符更新的有状态数组的最后一个值?的主要内容,如果未能解决你的问题,请参考以下文章
无法在额外属性扩展上获取属性“ndkVersion”,因为它不存在于... react-native 0.64.0