简体   繁体   English

React:组件仅在按钮的第二onClick上呈现新值

[英]React: component only rendering new values on second onClick of button

I making a react app and I have a parent component Search with child components Input and Result . 我制作了一个React应用,我有一个父组件Search和子组件InputResult Input has a drop down menu which passes a value, genreValue , to Search , through a callback function when a button is clicked. Input有一个下拉菜单,当单击按钮时,该菜单会通过回调函数将genreValue值传递给Search Search then makes an api call, which works fine. 然后搜索进行api调用,效果很好。

My problem is it takes two clicks of the button for the new API data to render. 我的问题是需要两次单击按钮才能呈现新的API数据。 Looking at other SO questions I suspect I need to pass genreValue as an argument to the cb function, or my onClick is only initialising, rather than invoking it on the first click. 查看其他SO问题,我怀疑我需要将genreValue作为参数传递给cb函数,否则我的onClick只是初始化,而不是在第一次单击时调用它。

It's a pretty simple app so I wouldn't think Flux etc would be needed. 这是一个非常简单的应用程序,因此我认为不需要Flux等。 My console logs seem to show the value being changed in the Search and Input components. 我的控制台日志似乎显示了SearchInput组件中正在更改的值。 So what am I doing wrong? 那我在做什么错?

Search.js 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 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;

In the handleGenre function, state may not have updated when this.getMovies is called. handleGenre函数中,调用this.getMovies时状态可能尚未更新。 You could change it to the following: 您可以将其更改为以下内容:

handleGenre(newGenre) { this.setState({ genreValue: newGenre }, function() { return this.getMovies(); }); },

Or, probably better practice would be to call this.getMovies in a componentDidUpdate lifecycle function if genreValue has changed: 或者,可能是更好的做法是调用this.getMoviescomponentDidUpdate如果生命周期功能genreValue发生了变化:

componentDidUpdate: function(prevProps, prevState) { if (prevState.genreValue !== this.state.genreValue) { this.getMovies(); } }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM