0

Need to delay the api update. Beacause when results of the api renders, some of the components delays a little bit and sometimes doesnt print it.

Tried the input user delay, but it was only for typing, so try differents ways to delay the api, but no luck

componentDidUpdate(prevProps, prevState) {
if (prevState.userInput !== this.state.userInput || 
      prevState.page !== this.state.page) {
        if (prevState.userInput !== this.state.userInput)
          this.setState({page: 1});
        if (this.state.userInput === '' && 
        (prevState.userInput !== this.state.userInput)) {
          fetch(API_POPULAR)
          .then(response => response.json())
          .then(json => {
            this.setState({
              selection: 'popular?',
              items: json.results, 
              isLoading: false,
              page: 1,
              max_pages: json.total_pages
             });
          });
}
remix23
  • 2,632
  • 2
  • 11
  • 21
Jonathan
  • 469
  • 1
  • 6
  • 20
  • 2
    It's not clear what exactly you want can you please explain a bit more – Black Mamba Aug 13 '19 at 12:41
  • Welcome to stackoverflow. As I understand you actually want to delay the api call. Do you want the same delay after each componentDidUpdate call, or do you want the api call to occur only once for a given amount of time? – remix23 Aug 13 '19 at 12:43
  • Looks like you're looking for a debounce method. You can use one from lodash and apply it to the function that modifies the input state. – Clarity Aug 13 '19 at 12:43
  • @remix23 delay after each componentDidUpdate call – Jonathan Aug 13 '19 at 12:45
  • Possible duplicate of [Perform debounce in React.js](https://stackoverflow.com/questions/23123138/perform-debounce-in-react-js) – Black Mamba Aug 13 '19 at 12:51
  • It seems the OP is not looking for a debounce – remix23 Aug 13 '19 at 13:36

2 Answers2

1

If you just want to delay the api call after each componentDidUpdate call, just wrap your api into the callback of a setTimeout:

    componentDidUpdate(prevProps, prevState) {
        const delay = 1000; // in ms
        if (
            prevState.userInput !== this.state.userInput || 
            prevState.page !== this.state.page
        ) {
            if (prevState.userInput !== this.state.userInput)
                this.setState({page: 1});
                if (
                    this.state.userInput === '' && 
                    (prevState.userInput !== this.state.userInput)
                ) {
                    setTimeout(
                        () =>
                            fetch(API_POPULAR)
                                .then(response => response.json())
                                .then(json => {
                                    this.setState({
                                        selection: 'popular?',
                                        items: json.results, 
                                        isLoading: false,
                                        page: 1,
                                        max_pages: json.total_pages
                                    });
                                 }),
                         delay
                    );
                }
            }
        }
    }

Be carefull thou as each call to componentDidUpdate will result in an asynchronous call to the api delayed by 1 second which may lead to weird behavior.

If you want to allow the user to interact with the UI and fetch something only after a given amount of time without new componentDidUpdate, you will need to use clearTimeout like so:

    if (this.lastCall) clearTimeout(this.lastCall);
    this.lastCall = setTimeout(........);

If that's still not what you are looking for, try and look debounce and throttle as comments above suggested.

remix23
  • 2,632
  • 2
  • 11
  • 21
1

what you can do is (Without using debounce, that's probably the best for these cases, but it's not a good idea to use it on the componentDidUpdate) wrap the whole execution (API call in this case) in a setTimeout, this way you could wait for as long as you want to make the call:

componentDidUpdate(prevProps, prevState) {
if (prevState.userInput !== this.state.userInput || 
      prevState.page !== this.state.page) {
        if (prevState.userInput !== this.state.userInput)
          this.setState({page: 1});
        if (this.state.userInput === '' && 
        (prevState.userInput !== this.state.userInput)) {
          setTimeout(() => {
            fetch(API_POPULAR)
            .then(response => response.json())
            .then(json => {
              this.setState({
                selection: 'popular?',
                items: json.results, 
                isLoading: false,
                page: 1,
                max_pages: json.total_pages
              });
           });
          }, TIME_TO_WAIT);
}
Alberto Perez
  • 2,561
  • 1
  • 14
  • 21