Search code examples
mobxmobx-reactreact-native-flatlist

React Native mobx binding to FlatList not working


I have a RN (0.44.2) mobx (3.1.10) app which uses a FlatList. I'm basically following https://blog.callstack.io/write-react-native-apps-in-2017-style-with-mobx-e2dffc209fcb

When using my own store, opposed to the examples, I'm having to use toJS() in order to get the FlastList to render

    // renders list
    <FlatList
      data={this.props.giphyStore.images.toJS()}
      keyExtractor={(_, i) => i}
      renderItem={({ item }) => <Text>found the data</Text>}
    />

    // does not render list
    <FlatList
      data={this.props.giphyStore.images}
      keyExtractor={(_, i) => i}
      renderItem={({ item }) => <Text>did not find the data</Text>}
    />

I'm really struggling to figure out why toJS() might be needed in some cases and not others.

My store is setting the images observable like this

async getImageList(query: string) {
  try {
    const requestURL = `${constants.GIPHY_ENDPOINT}${query}`
    const response = await axios.get(requestURL);
    const imgs = response.data.data.map((item) => {
      return { id: item.id, url: item.images.downsized.url }
    })
    this.images.replace(imgs)
  } catch (e) {
  }
}

As a follow up question, I'm not sure why I need to do the following this.images.replace(imgs) where as in the tutorial he simply did does this.tracks = response.data.tracks.items which triggers the observable just fine.

If anyone has suggestions, I would very much appreciate it.


Solution

  • This is because mobx's arrays are objects and the data in FlatList or in react native expects an array. You can read more about it in here and there.

    Also..., slice returns a shallow copy; a new array with the same contents, while toJS also converts the values inside the array (but only if they are observables).