If you are totally against setting state in a useEffect, how would you recommend doing this kind of thing? Assume a SPA.
63 likes 23 replies
Replies
Sam Minnée · Dec 1
If you don’t want to use tanstack query, I like to bundle this into a useAsyncMemo hook, so that the code isn’t repeated everywhere. But replacing it with tanstack query will give you caching / reuse, retries, loading statuses, timeouts, etc, which is very handy.
Lieke B 👩💻 · Dec 1
I feel like people mainly have a problem with people updating state from an effect ran that was triggered by another state change. This is basically just an onMount.
Maxence Poutord · Dec 2
I'm using TanStack Query. It can be handy if you have several pages with operations like this. Also it has an internal cache which is cool in the context of an SPA. tanstack.com/query/latest...
RαίX · Dec 1
You would have to track if component is mounted. In React 19 it could likely be done differently. Would be great if React Compiler would allow async client components…
Jasper 張 · Dec 1
This is a promise though, there is nothing wrong with setting state in a promise or event listener. I am against setting state directly inside of a useEffect.
Reed Harmeyer · Dec 3
Hoisted Hooks
Olivier THIERRY · Dec 1
What is the problem with setting state in a useEffect ? 🤔
Ray Thurn Void · Dec 6
For folks proposing react-query, it should not be a valid answer to this post since internally react-query does exactly what this code does. If react-query is allowed then there's nothing wrong with this code snippet.
Nat · Dec 2
That’s fine for a simple single request or simple PoCs, you don’t need to over complicate things. However in a real world projects, I like TanStack Query tanstack.com/query/latest or SWR swr.vercel.app as a lightweight alternative.
Pawel Kozlowski · Dec 1
Not a React answer but the principle is the same: I like to think about data fetching as a mapping of a reactive state => reactive response. Newly introduced Angular's resource, SolidJS resource (minimal APIs) and TanStack Query (a real lib) lets one think in the "mapping" mental model.
Sean Newell · Dec 1
By creating a parent component and suspense boundary. We greatly encourage/direct folks towards using a suspending, cacheable data loader (TSQ) and to place their suspense boundary in a direct parent of the consuming component. Suspense is the important recommendation imo.
Mark Erikson · Dec 1
I _assume_ people mean doing it synchronously in the effect, but I could be missing something
Mathieu · Dec 1
I would use vue 🤔
Ricky · Dec 1
This isn’t in the effect, it’s in the promise callback, so it’s fine but still has footguns because of race conditions. Better to use use().
Manu · Dec 1
Main reason why I like the approach of using loaders in remix/ react router. Both on the server or client depending the need. It saved me to keeping this useeffect boilerplates
Paxton · Dec 2
useSwr
Space Gravy · Dec 1
Would this actually violate the lint rule? You’re not calling the setter function in useEffect but passing it as a callback to “then”.
nox — oss/acc · Dec 1
Honestly just use @tanstack.com react-query's useQuery, it's so much cleaner for client side fetching. Or there's always the async RSC route.
Thorr ⚡️codinsonn.dev · Dec 1
react-query or even SWR There’s no better way to do it
Brittany Ellich · Dec 3
I would probably move the data call to its own custom hook, and do something like `useComponentData()` when setting the initial state. But I also probably wouldn't reject a PR that included the above, either.
Edun Omatseye · Dec 1
@tanstack.com query would do
Dominik 🔮 · Dec 1
The lint rule to avoid direct setState in useEffect allows this pattern: eslint-react.xyz/docs/rules/h...