反应本机FlatList对象显示

时间:2018-10-16 19:31:42

标签: javascript reactjs react-native

我具有要从AsyncStorage检索的以下对象,并且希望将其显示在FlatList中,但出现以下错误:

不变违规:不变违规:不变违规:不变违规:试图获取超出范围索引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 ",

  },
}

AsyncStorage中检索上述JSON,如下所示:

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数据?

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

您使用的async / await错误。无需调用.then,而是将对await的调用分配给一个变量(如果不返回值,则不分配它),然后将调用(或多个调用)包装到awaittry / 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乍一看似乎有点让人不知所措,但这是一种非常强大的方法,您可以完成很多工作。