sosick
sosick

Reputation: 622

React: why the state is updated correctly until the second time?

I'm fetching data (pics and descriptions) from server, and using them in infinite scroll. When I'm scroll to bottom of page I want to change state value (value of the page from which we collect data).

When I'm doing this, something goes wrong. State update correctly only on second and each next time.

Code:

class Gallery extends Component {
  state = {
    photos: [],
    searchValue: "dog",
    page: 1,
    totalPages: null
  };

  getPhotos = () => {
    const { photos, searchValue, page, totalPages } = this.state;

    axios.get(`api_key=${API_KEY}&tags=${searchValue}&page=${page}`)
      .then(res => {
        this.setState({
          photos: [...photos, ...res.data.photos.photo],
          totalPages: res.data.photos.pages
        });
        if (page < totalPages) {
          this.setState(prevState => ({ page: prevState.page + 1 }));
          console.log(page); // returns 1 on the first call, but should return 2;
        }
      })
  };

  render() {
    const { photos, page, totalPages, loading } = this.state;

    return (
      <div className={classes.Content}>
        <InfiniteScroll
          pageStart={page}
          loadMore={this.getPhotos}
          hasMore={page < totalPages}
          loader={<Spinner />}
        >
          <Photos photos={photos} />
        </InfiniteScroll>
      </div>
    );
  }
}

and now, the problem is here:

if (page < totalPages) {
    this.setState(prevState => ({ page: prevState.page + 1 }));
}

on the first function call, page is 1, but on my logic should be 2. On the next calls everything work good (page is 2, 3, 4 etc.). For now i'm loading two times the same photos. Can You help me?

Upvotes: 0

Views: 59

Answers (1)

Hemadri Dasari
Hemadri Dasari

Reputation: 33974

As we know setState in react is asynchronous so you can’t see the value immediately when modified.

To get the updated value you should do something like below

 getPhotos = () => {
      const { photos, searchValue, page, totalPages } = this.state;
    if (page < totalPages) {
          this.setState(prevState => ({ 
              page: prevState.page + 1 
          }), () => {
               console.log(this.state.page);//will print 2
             axios.get(`api_key=${API_KEY}&tags=${searchValue}&page=${this.state.page}`)
        .then(res => {
           this.setState({
              photos: [...photos, ...res.data.photos.photo],
              totalPages: res.data.photos.pages
          });
        })
      });
    }
  }

Upvotes: 4

Related Questions