Search code examples
react-query

Running into an issue with a mutation and component flickering with react-query


So, I am making a query everything my context API is updated via a form selection update..

So, order of operation is like so.

  1. User makes a change to a form by selecting (one of possible many) from dropdown.
  2. Change updates "context api" which resaturates the parent component.
  3. Because the form key/values changed, I fire a mutation.
  4. Mutation returns a value. So far, great.
  5. But, when I repeat step #1 - #4, another component flickers with that updated value because at some point the "const" that is expecting a value is undefined... THEN, it has a value..

So, like so..

has a value... ...query api call... has no value ...returns query has a value

const ProductPage = (props) => {
  const { question } = useContextStateWhatever();
  /* Queries */
  const { data = {}, isFetched } = useProductUpdatePrice({ questions });

  const value = derivePriceFromResponse(data.products);

  return (
   <SomeComponentRendered value={value} />
  )

So, you can see between the "old value" and request in query, that the passed "value" will be undefined. Then query returns, updated value.

I was hoping the query will return any previous value, but the "queryKey" changes with every selection of the form. Deep queryKey.

I was hoping I wouldn't have to then put this value into local state from within a useEffect, or use useRef and create hook to hand back "previous" value until new value is ready.... That's not what react-query is for, right? I mean, shouldn't I be able to make a query call whenever the "context api" changes, and not expect this latency diff of undefined. Any strategies to over come this?

Since the "queryKey" is different (mostly for normal form interaction) for each query, I can see how it can't hand back a previous value until it resolves etc.. any ideas?

Any thoughts?


Solution

  • I think the keepPreviousData: true option is what you are looking for. If the query key changes, you will the get the data from the previous query key, along with an isPreviousData: true flag. The background update will still happen, and then you’ll get the data for the new query key once it arrives. The query will stay in isSuccess status the whole time.