Reputation: 24
I'm getting data from API (using Redux Saga) and I want to show the data in a FlatList. In ComponentDidMount I'm dispatching the action to hit the API. Data are getting without any issue. But for the first time , data is not showing in the flatlist. If I enter Ctrl + S (Save) in VS code data is showing. I want to have set
class MovieDetailsScreen extends Component {
constructor(props) {
super(props);
this.state = {
data:[],
};
}
componentDidMount(){
this.props.getMovieData();
if(this.props.movieList){
this.setState({data:movieList})
}
}
renderItem = ({ item }) => {
return(
<View style={styles.mainContainer}>
<View style={styles.textContainer}>
<Text >{item.movieName}</Text>
<Text >{item.movieDescription}</Text>
</View>
)
}
render() {
return (
<View >
<FlatList
keyExtractor={(item, index) => index.toString()}
data={this.state.data}
renderItem={this.renderItem}
/>
</View>
);
}
}
function mapStateToProps(state) {
return {
movieList : state.movieListReducer.movieList
};
}
export function mapDispatchToProps(dispatch) { return{
getMovieData: () => dispatch(movieListActions.getMovieData()),
}
}
export default connect( mapStateToProps, mapDispatchToProps )(MovieDetailsScreen);
I tried adding a loader in flatlist until the data is getting loaded , but it's not working. Please note that I need to use setState({data:movieList}) because in future I have more implementations , so I couldn't use this.props.movieList in flatlist data
Upvotes: 0
Views: 782
Reputation: 2004
You should create a new function to hold the fetching of the data and to give you an option to create the loader.
First add a loading option to your state:
this.state = {
data:[],
loading: false,
};
Then create the function:
fetchMovieList = () => {
this.setState({ loading: true })
this.props.getMovieData()
.finally( () => {
this.setState({ loading: false })
if(this.props.movieList){
this.setState({data:movieList})
}
}
Call the function in componentDidMount:
componentDidMount(){
this.fetchMovieList();
}
and in your render() set according to loading if it true show an empty view and if it is false show the flat list:
render() {
if (this.state.loading) {
return (
<View>
<Text> Loading </Text>
</View>
);
}
return (
<View >
<FlatList
keyExtractor={(item, index) => index.toString()}
data={this.state.data}
renderItem={this.renderItem}
/>
</View>
);
}
Instead of the text loading you can use the ActivityIndicator provided by react-native. Please check if i missed any semicolon or parentheses.
Upvotes: 1
Reputation: 812
You should call the this.setState({data:movieList}) method in componentDidUpdate because componentDidMount only runs for the first time.
Your code should be like this,
componentDidMount(){
this.props.getMovieData();
}
// This method will execute everytime a state or props change.
componentDidUpdate(prevProps){
if(this.props.movieList != prevProps.movieList){
this.setState({data:this.props.movieList})
}
}
Upvotes: 1