简体   繁体   English

渲染前如何更新状态?

[英]How do i update my state before it renders?

constructor(props) {
super(props);
this.state = {
  movie: "Interstellar",
  movies: [],
  newMovieParsed: {
    movieTitle: '',
    moviePosters: '',
    moviePlot: '',
    movieGenre: '',
    movieBoxOffice: '',
    movieRatings: [],
    movieActors: '',
    imdbId: '',
  }
};

}

  onSubmit = movie => {
this.setState(state => ({ ...state, movie }));
this.componentWillMount();
};

  componentWillMount() {
    this.APIURL = `http://www.omdbapi.com/? s=${this.state.movie}&apikey=${API_KEY}`;
    console.log(this.APIURL);

fetch(this.APIURL)
  .then(resp => resp.json())
  .then(data => {
    const movies = data.Search;
    this.setState(state => ({
      ...state, movies
    }));


  });
}

Now in the render 现在在渲染中

<Search
          placeholder="Enter the title of a movie you wish to search and press Enter .."
          onSearch={(value) => this.onSubmit(value)}
          style={{ width: '100%' }}
        />

Everything works but when I put a new movie and press enter I have to enter twice. 一切正常,但是当我放新电影并按Enter时,我必须输入两次。 The first enter seems to be updating the state then the second updates the render. 第一个输入似乎正在更新状态,然后第二个更新渲染。 How do i update the state and render it with the first enter? 我如何更新状态并使用第一个Enter呈现它? I am also using Ant-design. 我也在使用Ant设计。

The main thing is your setState callback should either be the name of the function (no parenthesis) or an anonymous function that calls it: 最主要的是您的setState回调应该是函数的名称(不带括号)或调用它的匿名函数:

onSubmit = movie => {
this.setState(state => ({ ...state, movie }));
this.componentWillMount;
};

OR 要么

onSubmit = movie => {
this.setState(state => ({ ...state, movie }));
() => this.componentWillMount();
};

Other hints: Usually you don't call lifecycle methods directly (componentWillMount), and you don't need to do that much work in setState. 其他提示:通常,您不直接调用生命周期方法(componentWillMount),也不需要在setState中做太多工作。 You can set just the key you want to replace. 您可以仅设置要替换的密钥。

Here is some optimized code if you are interested: 如果您有兴趣,下面是一些优化的代码:

constructor(props) {
  super(props);
  this.state = {
    movie: "Interstellar",
    movies: [],
    newMovieParsed: {
      movieTitle: '',
      moviePosters: '',
      moviePlot: '',
      movieGenre: '',
      movieBoxOffice: '',
      movieRatings: [],
      movieActors: '',
      imdbId: '',
    }
  };
}

onSubmit = movie => {
  this.setState({movie}), this.fetchMovie); 
};

componentWillMount() {
  this.fetchMovie();
}

fetchMovie() {
  this.APIURL = `http://www.omdbapi.com/? s=${this.state.movie}&apikey=${API_KEY}`;
  console.log(this.APIURL);

  fetch(this.APIURL)
    .then(resp => resp.json())
    .then(data => {
      const movies = data.Search;
      this.setState(state => ({
        ...state,
        movies
      }));
    });
}

There is no reason to get whole list of movies every time you update state. 每次更新状态时,没有理由获得完整的电影列表。 In componentWillMount() you can do initial fetch of movies and then on submit you can just update the state with new movie. 在componentWillMount()中,您可以进行电影的初始获取,然后在提交时就可以使用新电影来更新状态。 If needed you can call React.forceUpdate() to trigger render method. 如果需要,您可以调用React.forceUpdate()来触发渲染方法。

constructor(props) {
    super(props);
    this.state = {
      movie: "Interstellar",
      movies: [],
      newMovieParsed: {
        movieTitle: '',
        moviePosters: '',
        moviePlot: '',
        movieGenre: '',
        movieBoxOffice: '',
        movieRatings: [],
        movieActors: '',
        imdbId: '',
       }
    };
  }
  componentWillMount() {
       this.getMovies();
  });
  getMovies = () => {
    this.APIURL = `http://www.omdbapi.com/? s=${this.state.movie}&apikey=${API_KEY}`;
      console.log(this.APIURL);

      fetch(this.APIURL)
       .then(resp => resp.json())
       .then(data => {
          const movies = data.Search;
          this.setState(state => ({
            ...state, movies
          }));  
    }
    onSubmit = movie => {
      this.setState(state => ({ ...state, movie }));
    };

 }

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

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