【问题标题】:React Native FlatList Object displayingReact Native FlatList 对象显示
【发布时间】:2019-03-21 10:05:13
【问题描述】:

我有以下从 AsyncStorage 中检索的对象,我想在 FlatList 中显示它,但我收到以下错误:

Invariant Violation: Invariant Violation: Invariant Violation: Invariant Violation: Tried to get frame for out of range index NaN

我的 JSON 格式是:

Object {
  "44": Object {
    "pro_id": "44",
    "pro_img": "url",
    "pro_name": " S4 ",
  },
  "52": Object {
    "pro_id": "52",
    "pro_img": "url",
    "pro_name": " S4 ",

  },
}

上面的 JSON 是从 AsyncStorage 检索到的,如下所示:

retrieveData = async () => {

    try {
       await AsyncStorage.getItem('userFavorites')
       .then(req => JSON.parse(req))
       .then(json => this.setState({ favPro:json }))

    } catch (error) {

    } 
}

我在FlatList 中渲染项目的方法是这样定义的:

 fav = ({ item }) => {
    return (
      <View>
      <Text>{item.pro_id+ item.pro_name}</Text>
      </View>
    )
}

最后,我将FlatList渲染如下:

<FlatList
          data={this.state.favPro}
          renderItem={this.fav}
          keyExtractor={item => item.pro_id}
        />

如何使用FlatList 组件显示我的 JSON 数据?

【问题讨论】:

  • Invariant Violation: Invariant Violation: Invariant Violation: Invariant Violation: 试图获取超出范围索引 NaN 的帧

标签: javascript reactjs react-native


【解决方案1】:

FlatList 组件需要 data 属性的数组输入。根据您的 JSON 格式,您似乎传递的是对象而不是数组。

考虑对您的渲染方法进行以下调整:

// Convert object to array based on it's values. If favPro not 
// valid (ie during network request, default to an empty array)
const data = this.state.favPro ? Object.values(this.state.favPro) : []

<FlatList
  data={data}
  renderItem={this.fav}
  keyExtractor={item => item.pro_id}
/>

【讨论】:

    【解决方案2】:

    您错误地使用了async / await。不是调用.then,而是将调用await 分配给一个变量(或者如果它没有返回值,则不分配它)并将对await 的调用(或调用)包装在try / catch 块中. await 关键字将自动处理resolvereject,以便您获得适当的信息。

    retrieveData = async () => {
      try {
        const data = JSON.parse(await AsyncStorage.getItem("userFavorites"))
        this.setState({ favPro: data })
      } catch (error) {
        console.error(error)
        this.setState({ favPro: [] })
      }
    }
    

    您还需要传递一个数组,您的数据的形状看起来像一个对象,但它应该是一个对象数组。这不是一个非常困难的转换,如果您需要,我可以提供一个辅助函数。

    编辑:如果需要将对象转为数组,可以使用reduce函数

    const data = {
      '44': { a: 2 },
      '55': { b: 3 },
    }
    
    const dataArr = Object.keys(data).reduce(
      (arr, key) => arr.concat(data[key]),
      []
    )
    

    通过使用Object.keys,我们可以按名称为每个对象。然后调用reduceObject.keys 返回的数组,传递一个函数作为第一个参数,一个空数组作为第二个参数。第二个参数作为第一个参数arr自动传递给函数,我们传递的函数的第二个参数是对象的键。然后只需使用concat 将对象添加到数组即可。

    Array.reduce 乍一看可能有点不知所措,但它是一种非常强大的方法,你可以用它完成很多工作。

    【讨论】:

    • 虽然 Dacre 的回答解决了这个问题,但是如果你不介意更多信息,你能证明一个辅助函数吗?
    • @othmansafadi 确定我添加了一些示例代码!不要忘记接受 Dacre 的回答,并为对您也有帮助的回答点赞
    • 谢谢,如果您不介意我如何从该列表或 AsyncStorage 中删除项目,以便更具体地在哪里 pro_id = x ..?
    • 当你减少时,你可以检查,if(!data[key].id == unwantedId) 所以任何与unwantedId 匹配的东西都不会添加到列表中
    猜你喜欢
    • 1970-01-01
    • 2022-12-18
    • 2019-10-02
    • 2022-01-22
    • 1970-01-01
    • 2021-10-21
    • 1970-01-01
    • 1970-01-01
    • 2021-06-29
    相关资源
    最近更新 更多