React:组件仅在第二次点击按钮时呈现新值
React: component only rendering new values on second onClick of button
我正在制作一个 React 应用程序,并且我有一个父组件 Search
和子组件 Input
和 Result
。 Input
有一个下拉菜单,它在单击按钮时通过回调函数将值 genreValue
传递给 Search
。搜索然后进行 api 调用,效果很好。
我的问题是需要单击两次按钮才能呈现新的 API 数据。查看其他 SO 问题,我怀疑我需要将 genreValue
作为参数传递给 cb 函数,或者我的 onClick 只是初始化,而不是在第一次点击时调用它。
这是一个非常简单的应用程序,所以我认为不需要 Flux 等。我的控制台日志似乎显示 Search
和 Input
组件中正在更改的值。
那我做错了什么?
Search.js
let Search = React.createClass ({
getInitialState(){
return {
movies: ['Men In Black'],
genreValue: '12'
};
},
componentDidMount(){
this.getMovies()
},
getMovies(){
let genre = this.state.genreValue;
let url = `http://api.themoviedb.org/3/discover/movie?${key}&with_genres=${genre}`;
Request.get(url).then((response) => {
console.log('response.body.results', response.body.results)
this.setState({
movies: response.body.results.map(function(movie){
return movie.title
})
});
});
},
handleGenre(newGenre) {
this.setState({ genreValue: newGenre })
return this.getMovies();
},
render(){
console.log(this.state.movies)
console.log('genreValue state', this.state.genreValue)
return (
<div>
<Input genre={this.state.genreValue} onGenreChanged={this.handleGenre}/>
<ul>
{this.state.movies.map( function(movie){
return <Results key={movie.id} data={movie}/>;
})}
</ul>
</div>
);
}
});
export default Search;
Input.js
let Input = React.createClass ({
selectHandler(){
return this.props.onGenreChanged(this.refs.genre.value);
},
render() {
console.log('genreValue prop', this.props.genre);
console.log('refs', this.refs.genre)
return <div>
<select ref="genre">
<option value="28">Action</option>
<option value="12">Adventure</option>
<option value="16">Animation</option>
<option value="35">Comedy</option>
<option value="80">Crime</option>
<option value="99">Documentary</option>
<option value="18">Drama</option>
<option value="10751">Family</option>
<option value="14">Fantasy</option>
<option value="10769">Non-english</option>
<option value="36">History</option>
</select>
<button onClick={this.selectHandler} value="Go">Go</button>
</div>
}
});
export default Input;
在handleGenre
函数中,调用this.getMovies
时状态可能没有更新。您可以将其更改为以下内容:
handleGenre(newGenre) {
this.setState({ genreValue: newGenre }, function() {
return this.getMovies();
});
},
或者,如果 genreValue
发生变化,可能更好的做法是在 componentDidUpdate
生命周期函数中调用 this.getMovies
:
componentDidUpdate: function(prevProps, prevState) {
if (prevState.genreValue !== this.state.genreValue) {
this.getMovies();
}
}
我正在制作一个 React 应用程序,并且我有一个父组件 Search
和子组件 Input
和 Result
。 Input
有一个下拉菜单,它在单击按钮时通过回调函数将值 genreValue
传递给 Search
。搜索然后进行 api 调用,效果很好。
我的问题是需要单击两次按钮才能呈现新的 API 数据。查看其他 SO 问题,我怀疑我需要将 genreValue
作为参数传递给 cb 函数,或者我的 onClick 只是初始化,而不是在第一次点击时调用它。
这是一个非常简单的应用程序,所以我认为不需要 Flux 等。我的控制台日志似乎显示 Search
和 Input
组件中正在更改的值。
那我做错了什么?
Search.js
let Search = React.createClass ({
getInitialState(){
return {
movies: ['Men In Black'],
genreValue: '12'
};
},
componentDidMount(){
this.getMovies()
},
getMovies(){
let genre = this.state.genreValue;
let url = `http://api.themoviedb.org/3/discover/movie?${key}&with_genres=${genre}`;
Request.get(url).then((response) => {
console.log('response.body.results', response.body.results)
this.setState({
movies: response.body.results.map(function(movie){
return movie.title
})
});
});
},
handleGenre(newGenre) {
this.setState({ genreValue: newGenre })
return this.getMovies();
},
render(){
console.log(this.state.movies)
console.log('genreValue state', this.state.genreValue)
return (
<div>
<Input genre={this.state.genreValue} onGenreChanged={this.handleGenre}/>
<ul>
{this.state.movies.map( function(movie){
return <Results key={movie.id} data={movie}/>;
})}
</ul>
</div>
);
}
});
export default Search;
Input.js
let Input = React.createClass ({
selectHandler(){
return this.props.onGenreChanged(this.refs.genre.value);
},
render() {
console.log('genreValue prop', this.props.genre);
console.log('refs', this.refs.genre)
return <div>
<select ref="genre">
<option value="28">Action</option>
<option value="12">Adventure</option>
<option value="16">Animation</option>
<option value="35">Comedy</option>
<option value="80">Crime</option>
<option value="99">Documentary</option>
<option value="18">Drama</option>
<option value="10751">Family</option>
<option value="14">Fantasy</option>
<option value="10769">Non-english</option>
<option value="36">History</option>
</select>
<button onClick={this.selectHandler} value="Go">Go</button>
</div>
}
});
export default Input;
在handleGenre
函数中,调用this.getMovies
时状态可能没有更新。您可以将其更改为以下内容:
handleGenre(newGenre) {
this.setState({ genreValue: newGenre }, function() {
return this.getMovies();
});
},
或者,如果 genreValue
发生变化,可能更好的做法是在 componentDidUpdate
生命周期函数中调用 this.getMovies
:
componentDidUpdate: function(prevProps, prevState) {
if (prevState.genreValue !== this.state.genreValue) {
this.getMovies();
}
}