2

So I'm building a React application that is making API calls to receive a random object containing a quote, author, and some other information. When the component mounts(on page refresh) the object is randomized. However, the button bound to the same function that initially pulls the API only receives the same object as when the page loaded. The randomization is provided from the endpoint and not within my code.

Not sure why this wouldn't work as the data received is unique on page refresh, but not on the onClick event.

So here's some of my code that I'm using:

My API fetch function:

httpCallout(){
    fetch('https://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1')
    .then(response => response.json())
    .then((data) => {
      const quote = data[0].content;
      this.setState({
        quote: quote,
        author: data[0].title
      });
    });
  }

The call within the lifecycle function:

  componentDidMount(){
    this.httpCallout();

  }

and then the element

<button id="new-quote" className="btn btn-light" onClick={this.httpCallout}>New Quote</button>

So again, I'm expecting to be receiving a new object containing new data on each click event, however, I'm being fed the same data as on the page load.

EDIT: It was simply data being cached. I added {cache: "no-cache"} into the fetch request and it was solved. The question has been marked as a duplicate, however I find the solution required to be slightly different since my issue was using the fetch API and not using jQuery or AJAX.

jacksons123
  • 161
  • 9

3 Answers3

2

It appears that your browser is simply caching the response. You can fix that:

fetch('https://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1&_=' + Date.now())

By adding an extra (essentially random) parameter, the browser treats it as a new URL.

You can see the effect for yourself by putting your current URL into a browser tab and reloading it a few times.

Pointy
  • 371,531
  • 55
  • 528
  • 584
  • This works, however I like @Titenis 's response a bit better due to leaving the endpoint intact. Is there any advantage to modifying the endpoint compared to not storing the API cache? – jacksons123 Jun 04 '19 at 12:20
  • @jacksons123 both approaches do pretty much exactly the same thing, so it's your choice. – Pointy Jun 04 '19 at 12:24
  • Thanks so much again, I could definitely see this being interesting for creating a random call for endpoints that don't have randomization! – jacksons123 Jun 04 '19 at 14:29
2

disable response caching with {cache: "no-cache"}:

fetch(
'https://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1',
 {cache: "no-cache"}
)

more info: https://hacks.mozilla.org/2016/03/referrer-and-cache-control-apis-for-fetch/

Titenis
  • 519
  • 6
  • 13
0

Add {cache: "no-store"} to your fetch call:

httpCallout = () => {
fetch(
  "https://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1",
  { cache: "no-store" })
  .then(response => response.json())
  .then(data => {
    // ...
  });
};

Working example (using Hooks) here: https://codesandbox.io/s/serverless-hooks-fchnk

Will Jenkins
  • 7,578
  • 1
  • 20
  • 35