最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React Native FlatList Object displaying - Stack Overflow

programmeradmin1浏览0评论

I have the below object that I am retrieving from the AsyncStorage, and I want to display it in a FlatList but I am getting the following error:

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

My JSON format is:

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

  },
}

The JSON above is retrieved from AsyncStorage like so:

retrieveData = async () => {

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

    } catch (error) {

    } 
}

My method for rendering items in the FlatList is defined like this:

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

Finally, I render the FlatList as follows:

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

How I can display my JSON data using the FlatList ponent?

I have the below object that I am retrieving from the AsyncStorage, and I want to display it in a FlatList but I am getting the following error:

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

My JSON format is:

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

  },
}

The JSON above is retrieved from AsyncStorage like so:

retrieveData = async () => {

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

    } catch (error) {

    } 
}

My method for rendering items in the FlatList is defined like this:

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

Finally, I render the FlatList as follows:

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

How I can display my JSON data using the FlatList ponent?

Share Improve this question edited Oct 17, 2018 at 0:12 Dacre Denny 30.4k5 gold badges51 silver badges66 bronze badges asked Oct 16, 2018 at 19:31 othman safadiothman safadi 3314 silver badges12 bronze badges 1
  • Invariant Violation: Invariant Violation: Invariant Violation: Invariant Violation: Tried to get frame for out of range index NaN – othman safadi Commented Oct 16, 2018 at 19:38
Add a ment  | 

2 Answers 2

Reset to default 5

The FlatList ponent expects an array input for the data prop. Based on your JSON format, it appears you're passing in an object rather than an array.

Consider the following adjustment to your render method:

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

You're using async / await incorrectly. Instead of calling .then you assign your call to await to a variable (or don't assign it if it does not return a value) and wrap the call (or calls) to await in a try / catch block. The await keyword will automatically handle resolve and reject so you get the appropriate information.

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

You also need to pass an array, the shape of your data looks like an object, but it should be an array of objects. This is not a terribly difficult transformation and I can provide a helper function if you need it.

edit: if you need to convert an object into an array, you can use the reduce function

const data = {
  '44': { a: 2 },
  '55': { b: 3 },
}

const dataArr = Object.keys(data).reduce(
  (arr, key) => arr.concat(data[key]),
  []
)

By using Object.keys we can each object by name. Then call reduce and the array returned by Object.keys, passing a function as the first argument, and an empty array as the second argument. The second argument is automatically passed to the function as the first argument, arr, and the second argument of the function we pass is the key of the object. Then it's just a matter of adding the objects to the array using concat.

Array.reduce can seem a little overwhelming at first but it's a very powerful method and you can get a lot done with it.

发布评论

评论列表(0)

  1. 暂无评论