繁体   English   中英

在renderMenuItemChildren中未定义“ this”

[英]'this' undefined in renderMenuItemChildren

我正在使用react-bootstrap-typeahead异步搜索 renderMenuItemChildren方法中,我想调用另一个方法handleSubmit来获取所选项目的详细信息。

thisrenderMenuItemChildren内部renderMenuItemChildren ,因此我无法调用该方法。 任何帮助表示赞赏。

PS我仍在学习反应,因此可能无法识别一个愚蠢的错误。

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      searchTitle: '',
      defaultUrl: 'http://www.omdbapi.com/?t=arrival'
    };
    this.handleSearch = this.handleSearch.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.fetchApiData = this.fetchApiData.bind(this);
  }

  componentDidMount() {
    this.fetchApiData(this.state.defaultUrl);
  }

  fetchApiData(url){
    fetch(url) 
     .then((result) => {
        return result.json()
     })
     .then((json) => {
        if(json.Response === "True"){
          this.setState({
            title: json.Title,
            year: json.Year,
            released: json.Released,
            runtime: json.Runtime,
            genreList: json.Genre,
            actors: json.Actors,
            plot: json.Plot,
            poster_url: json.Poster,
            rating: json.imdbRating,
            boxOffice: json.BoxOffice,
            votes: json.imdbVotes,
            response: json.Response
        });
      }
      else {
        this.setState({
          response: json.Response,
          error: json.Error
        });
      }
    })
    .catch((err) => {
      console.log(err);
    })
  }

  handleSubmit(query){
    if (!query) {
      return;
    }
    this.fetchApiData(`http://www.omdbapi.com/?t=${query}`);
  }

  handleSearch(query) {
    if (!query) {
      return;
    }

    fetch(`http://www.omdbapi.com/?s=${query}`)
      .then((result) => {
        return result.json()
      })
      .then((json) => {
        //console.log(json.Search);
        this.setState({
          options: json.Search
        })
      });
  }

  renderMenuItemChildren(option, props, index) {
    return (
      <div key={option.imdbID} onClick={() => 
        this.handleSubmit.bind(option.Title)}>
        <span>{option.Title}</span>
      </div>
    );
  }

  render() {
    return (
      <div className="row">
        <div className="col-xs-12 col-lg-10 col-lg-offset-1">
          <div className="App-header col-xs-12">
            <div className="row">
              <div className="col-xs-12 col-sm-6 col-lg-5">
                <h1><a href="http://www.omdbapi.com/" className="omdb-link" title="The Open Movie Database">OMDb</a></h1>
              </div>
              <div className="col-xs-12 col-sm-6 col-lg-7">

                <AsyncTypeahead
                  ref="typeahead"
                  {...this.state}
                  labelKey="Title"
                  onSearch={this.handleSearch}
                  options={this.state.options}
                  placeholder='Search Title'
                  className="search-input-box"
                  renderMenuItemChildren={this.renderMenuItemChildren}
                />
              </div>
            </div>
          </div>
          <SearchBody data={this.state} />
      </div>
    </div>
    );
   }
  }

您还需要在构造函数中绑定函数renderMenuItemChildren

添加:

this.renderMenuItemChildren = this.renderMenuItemChildren.bind(this);

这是一篇不错的小博客文章,提供了几种方法:说我喜欢lodash的bindAll的博客文章

_.bindAll(this, function1, function2, function3)

您需要对构造函数中的其他方法( handleSearchhandleSubmit等)进行处理:

this.renderMenuItemChildren = this.renderMenuItemChildren.bind(this);

(或其他几种方法,但这是您用于其他方法的方法,所以...)

尽管构造函数中的renderMenuItemChildren.bind(this)绝对可以工作,但是es6类还允许您将箭头函数表达式用作类方法。 这将自动this (或换句话说,上下文)绑定到该方法,减少样板代码的数量,并使组件更易于阅读。

因此您的代码可能是这样的:

class App extends Component {
  constructor(props) {
  super(props);
    this.state = {
      searchTitle: '',
      defaultUrl: 'http://www.omdbapi.com/?t=arrival'
    };
  }

  // etc...

  renderMenuItemChildren = () => {
    // do stuff
  }
}

您在这里不需要=>函数。 您可以使用以下代码将标题值传递回handleSubmit()

renderMenuItemChildren(option, props, index) {
  return (
    <div key={option.imdbID} onClick={this.handleSubmit.bind(this, option.Title)}>
      <span>{option.Title}</span>
    </div>
  );
}

暂无
暂无

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

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