Reputation: 12719
I am trying to fetch an array of movies and after it fetches the list it updates the state and the list should render, but the problem is the render method never calls from inside the axios callback, here is my code below
export default class Movies extends Component {
constructor(props){
super(props);
this.state={movies:[]};
}
componentDidMount(){
axios.get('URL')
.then(response => {
this.setState({movies:response.data});
console.log("Movies",this.state);// I get the values here see screenshot..
});
}
render(){
return(
<div className="row">
<div className="col-md-3">
<MovieList movies={this.state.movies}/>
</div>
<div className="col-md-6">Movie Details</div>
</div>
);
}
}
As you can see the code above, in function componentDidMount
in the axios callback I am setting the response values to the state, but it doesn't call the render after doing it, the block does execute well as I get the log properly see screenshot below
I am not understanding why it doesn't call render()
? I have tried couple of solutions available but none works for me, if I hardcode the videos array in default state it works fine, please help if anyone know the solution.
Update(Adding MovieList Code)
class ListItem extends Component {
render(){
return(
<li className="list-group-item">{this.props.moviename}</li>
);
}
}
export default class MoviesList extends Component {
constructor(props) {
super(props);
console.log("Props",props);
this.state={movies:props.movies};
}
renderList(){
const items=this.state.movies.map((movie) => <ListItem moviename={movie.name} key={movie.name}/>);
return items;
}
render(){
return(
<ul className="list-group">
<li className="list-group-item"><h3>Movies</h3></li>
{this.renderList()}
</ul>
);
}
}
Thanks.
Upvotes: 1
Views: 821
Reputation: 1673
You should consider making your MoviesList stateless:
export default class MoviesList extends Component {
constructor(props) {
super(props);
console.log("Props",props);
//If your component won't alter movies list by itself - there's no point to manage its "state"
//this.state={movies:props.movies};
}
renderList(){
//Use props here instead
const items=this.props.movies.map((movie) => <ListItem moviename={movie.name} key={movie.name}/>);
return items;
}
render(){
return(
<ul className="list-group">
<li className="list-group-item"><h3>Movies</h3></li>
{this.renderList()}
</ul>
);
}
}
Generally, you should strive to dumbing-down your components whenever possible.
Upvotes: 1
Reputation: 194
The problem you are getting is in ListItem Component. In order to get it work you need to work with componentWillReceiveProps
In this case, construct is called only once Because of that your component won't update. You need to use function componentWillReceiveProps , this function will run every time component receive new data.
Example:
componentwillreceiveprops(nextProps){
this.setState({
movies: nextProps.movies
})
}
Upvotes: 2