Using useQuery, setInterval and useEffect in the same component
Hello everyone! I'm pretty new in using react-query and I have a hopefully simple question:
I have my
useQuery function that is wrapped in a getItems function, then I have a setInterval that updates a component state every second, to display the current hour. The fact that the state related to the interval is updated re-triggers the render of the page, so it re-triggers the getItems function every time. Fortunately useQuery is powerful, so it's not doing API call to backend. But it keeps re-fetching the items object, so everything using this object is re-rendered.
Before I was using useEffect for fetching the APIs, so the content of fetched items was kept, but now I've put my getItems ouside of useEffect.
What should I do to resolve this problem?
code:
8 Replies
conscious-sapphireOP•3y ago
Update: Solved it using
useRef instead of useState. But if you have other hints that would be appreciated!
The thing is: updating every state cause a re-trigger of the useQuery function, it doesn't seem like the perfect way to handle data from backend, expecially if those data doesn't change and it's only a state update.inland-turquoise•3y ago
Why don’t you you just have it a different component?
optimistic-gold•3y ago
react query returns a stable reference for
data whenever it's served from cache. So when you have const {data} = useQuery(...), data should remain stable.
Can you show what's inside useGetItems()?fair-rose•3y ago
yeah I'd put the interval into the component that renders the timer to minimize the impact. but also:
data returned from useQuery is referentially stable, so you'll always get back the same list of items. How is this different from the useEffect before?conscious-sapphireOP•3y ago
Thank you all for the responses! Putting the timer in a different component is a great idea!
I will share with you a bit of the structure of my code, so maybe you can give me some more hints:
I have some questions for you:
- In your opinion is it good to handle the global error and the success in a separate file to make it re-usable and not duplicate code or it's better to put it into the same file of the component?
- Is using useQuery this way useful related to the fact the data is stable?
For @TkDodo 🔮 : the difference using useEffect is that putting the API call in useEffect is triggered only when the page is loaded (using
useEffect(()=>{},[]), but using react-query at top level, will reTrigger useGetItems() at each re-render.
P.s. Don't blame me for using POST requests to get content, not my design choice. Unfortunately the project is not mine and I'm only FE devfair-rose•3y ago
but using react-query at top level, will reTrigger useGetItems() at each re-render.it doesn't matter that
useGetItems() is "triggered" again. It doesn't trigger a request just because it renders, and it doesn't give you a new object. It will give you exactly the same thing no matter how often it renders
other things I'm seeing:
- params should be part of your QueryKey. This is really important to avoid all sorts of issues
- not sure what the onError handler is doing, but it seems like it copies errors somewhere? That shouldn't be necessary
- onSuccess like that is a no-op. you can't return things from onSuccessconscious-sapphireOP•3y ago
Thank you very much! Super helpful!
Last questions and I will leave you in peace xD
- What do you mean by
onError not necessary? I have a global error state handling, rendering different components based on error, so I'm using a global state (through Zustand) to handle all sort of errors. Do you have better ways to do this? If you have some docs about it I would be glad to read them.
- I'm encountering another issue, before I had a useState containing my object, so when I was updating a text field I updated the object's key I needed and then saved the new state. Being a text field, I can't do an API call with useMutation every time I insert a new letter. How do you handle this? I would create a state only for the text input, but for taking it simple I would prefer to edit the item state direcly, without adding states.
EDIT: for second question I found your article (https://tkdodo.eu/blog/react-query-and-forms), I read it and sort of understood how to do it, but if you have some more explanations they are more than welcome! However, we don't have a form library yet, and being a big project, inserting it now would become difficult.
Here, https://stackoverflow.com/questions/42550341/react-trigger-onchange-if-input-value-is-changing-by-state some folks suggest to use states to track local changes, what do you think about this?Stack Overflow
React: trigger onChange if input value is changing by state?
Edit: I don't want to call handleChange only if the button has been clicked. It has nothing to do with handleClick. I gave an example in the @shubhakhatri answer's comment.
I want to change the in...
fair-rose•3y ago
for global error handling, I would use error boundaries or the global onError callback on the queryCache, depending on what you are doing with the error: https://tkdodo.eu/blog/react-query-error-handling
React Query Error Handling
After covering the sunshine cases of data fetching, it's time to look at situations where things don't go as planned and "Something went wrong..."