gpt4 book ai didi

javascript - 将数据加载到 React Native FlatList

转载 作者:数据小太阳 更新时间:2023-10-29 05:28:25 26 4
gpt4 key购买 nike

我完全承认我现在对 Reactive Native 还很陌生,所以我预计这是一个简单的答案和一个潜在的愚蠢问题 :) 事实上,这本身可能不是 RN 问题,因为我会解释如下。

我有以下代码:

class MyScreen extends React.Component {

constructor(inProps) {
super(inProps);
this.state = { listData : [ ] };
}

render() { return (
<View>
<FlatList data={ this.state.listData }
renderItem={ ({item}) =>
<Text>{item.firstName} {item.lastName}</Text>
}
/>
</View>
); }

async componentDidMount() {
const data = [ ];
let keys = await AsyncStorage.getAllKeys();
keys.forEach(async function(inKey) {
let obj = await AsyncStorage.getItem(inKey);
obj = JSON.parse(obj);
data.push(obj);
});
this.setState({ listData : data });
};

}

目标只是从 AsyncStorage 加载数据并将其转储到列表中。看起来很基本,对吧?不幸的是,我无法让它工作:列表是空的。

现在,让我们来谈谈愚蠢的事情:是的,确实存储了数据,是的,它的格式是正确的(我知道这一点是因为如果我简单地获取一个特定的项目并将其 push() 到数据中,那么它就会出现在按预期列出)。

事实上,我知道问题出在哪里:setState() 调用在 keys.forEach() 调用完成之前执行。我知道这一点,因为如果我用这个替换 setState() 调用:

setTimeout(function() {
this.setState({ listData : data });
}.bind(this), 1000);

...然后我的列表突然按预期填充(我也可以在其中放置一些 console.log() 并看到 keys.forEach() 调用之后的那个实际上在键内的那些之前执行。对于每个())。我也知道,显然 getItem() 调用在调用 JSON.parse() 之前正在等待,否则这根本无法工作。

换句话说:我知道这是由这段代码的异步性质造成的。我似乎无法弄清楚的是如何正确编写它以避免这种情况。

我正在查看它,我在想“好吧,keys.forEach() 是一个阻塞调用,所以它怎么可能在 setState() 调用之前无法完成,特别是考虑到键的异步用法。 forEach() 回调和内部 getItem() 调用上的 await 用法?”...我唯一的想法是在 keys.forEach() 调用前放置一个异步,但这没有任何区别。

所以,这似乎本质上是一个基本的 JavaScript 问题,但我似乎无法解决它......但另一方面,我不确定我是否正在尝试以某种方式做到这一点我根本不应该在 RN 土地上,也许这才是真正的问题。

请注意,由于流经应用程序(添加是在另一个屏幕上完成的),数据必须从 AsyncStorage 动态提取,所以在我看来,尝试在 componentDidMount() 中加载它是有意义的,我是只是挂断了所涉及调用的异步性质。

有什么建议吗?

谢谢!

编辑:我还应该提到,我知道我可以解决这个问题的一种方法是完全删除异步性质:而不是存储单个数据项,而是将所有内容存储在 AsyncStorage 中的单个对象中。然后我可以读取一个项目,它将是一个数组(或将包含一个数组),然后唯一的异步部分是 getItem() 调用,但我可以使用它的回调版本并使其以这种方式工作.. .而且我根本不反对这种方法,但在这一点上,我真的很想了解我做错了什么,除了学习一些东西之外没有其他原因,因为这似乎应该有效:)

最佳答案

keys.forEach 在它自己的范围内(在它自己的回调函数中)执行代码,这会破坏你的 async/await 对。

改为这样做:

for (let inKey of keys) {
let obj = await AsyncStorage.getItem(inKey);
obj = JSON.parse(obj);
data.push(obj);
}

如果你真的想要forEach,你必须自己写一个返回Promise的版本,所以你可以在上面 Hook await :

await keys.awaitableForEach(async function(inKey) {

关于javascript - 将数据加载到 React Native FlatList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47860353/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com