Reputation: 13
I'm new to React Native and confused on how to properly utilize the provided Fetch API.
The call itself (as outlined here: http://facebook.github.io/react-native/docs/network.html) is straightforward, and I can log out a successful response, but when it comes time to render the data, it's undefined.
I would expect that I could define an empty 'movies' array, and then replace it by calling 'setState' from componentDidMount(), which would trigger a re-render. Is this assumption incorrect?
The code sample below results in the following error:
'undefined is not an object (evaluating 'allRowIDs.length')
Thanks in advance for any help!
import React, { Component } from 'react';
import { AppRegistry, ListView, Text, View } from 'react-native';
class ReactNativePlayground extends Component {
constructor() {
super();
this.state = {
movies: []
}
}
componentDidMount() {
fetch('https://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
movies: responseJson.movies
})
})
.catch((error) => {
console.error(error);
});
}
render() {
return (
<View>
<Text>test</Text>
<ListView
dataSource={this.state.movies}
renderRow={(row) => <Text>{row.title}</Text>}
/>
</View>
)
}
}
AppRegistry.registerComponent('ReactNativePlayground', () => ReactNativePlayground);
Upvotes: 1
Views: 585
Reputation: 15616
That's because you need to place the data into a ListView.DataSource
:
constructor (props) {
super(props);
const ds = new ListView.DataSource({
rowHasChanged: (a, b) => a !== b
})
this.state = {
movies: ds.cloneWithRows([])
}
}
// Inside the response JSON:
this.setState({
movies: this.state.movies.cloneWithRows(responseJson.movies)
});
The React Native ListView docs demonstrate this kind of setup. Using the datasource allows for optimisations to be made when rendering lists of data (notice the rowHasChanged
function for instance - which prevents needless re-rendering of a row when the data hasn't altered.
Upvotes: 2