Search code examples
reactjsreact-contextreact-query

Best strategy when dealing with a react-query mutation AND react context


I am having a bit of an issue. I am using react context api for one section of my site. Its a form that every selection then calls a react-query mutation (I don't have to do a mutation).

Problem arises because when a user makes a selection, it adds to a deeply nested context state object. So, I have like 3 actions that all update this deeply nested state.. ie, input/checkbox/dropdown... BUT after each action, I need to fire this mutation which then updates the state with a price.....

I am having an issue integrated this api (mutation) Into this context api.. any suggestions.. ie..

--- user clicks checkbox
------- update context state inside a deeply nested object
----------- ** Need to fire an api WITH this update state (the whole object) **
--------------- response from API updates this state with an updated price

--- user selects dropdown
------- update context state inside a deeply nested object
----------- ** Need to fire an api WITH this update state (the whole object) **
--------------- response from API updates this state with an updated price

The problem arises is that I get in an infinite loop inside the component with useEffect unless i use this "deeply nested object" but since its nested, it never "updates".. so it just fires once.

What is your strategy for updating context api state, THEN based on that state firing an API, which in turn 'updates the state'...


Solution

  • What is your strategy for updating context api state, THEN based on that state firing an API, which in turn 'updates the state'...

    With react-query, you'd do a useQuery and create a queryKey that contains all the client state (checkbox state, dropdown selection etc), something like:

    const useSomethingQuery = () => {
      const userInput = useMyContextValue()
      return useQuery(
        ['something', userInput],
        () => fetchSomething(userInput),
        { enabled: !!userInput }
      )
    }
    

    a couple of things going on here:

    • every time the userInput from context changes, the queryKey changes, and react-query will fire a new request when that happens
    • the userInput is basically all the "dependencies" for that query - can be a deeply nested object, doesn't have to be referentially stable, react-query will handle that
    • the query is disabled as long as we have no userInput and will enable once the first selection is made. This is optional of course.
    • You can use that custom hook wherever you need the data, so no need to put the resulting data into context or anything.