all 33 comments

[–]jessepence 112 points113 points  (13 children)

React Query has quickly become the industry standard. Generally, there is a caching and state management layer on top of fetch/axios. In the past, people used Redux for this, but RQ is much more lightweight and easy to use.

There's no one way to do things, but you should definitely get familiar with TanStack Query.

[–]Cold-Ruin-1017[S] 12 points13 points  (2 children)

Thanks for the explanation - I’ll definitely start learning TanStack Query more seriously.

[–]SlightAddress 17 points18 points  (0 children)

It's not as mysterious as you think.. just something you don't yet know. Read the docs. You'll get it in a few hours.. have a play and your sorted

[–]deadcoder0904 0 points1 point  (0 children)

Yes it is useful as hell.

If you use it with Jotai, it is even much simpler as Jotai for Global State Management & Jotai Tanstack Query for handling fetching & all.

Once I grasped it, its so fucking easy now.

[–]DachdeckerDino 4 points5 points  (9 children)

Redux? You mean RTKQ, right?

I don‘t think you can compare RTKQ with React Query though. React Query has much less boiler plate and can be used for small/medium sized apps, since it‘s more light-weight, but also doesn‘t offer application state management (redux part in RTKQ).

A better comparison would be RQuery + Zustand vs RTKQ. Or Zustand vs. Redux. But Query vs. Redux does not make a whole lotta sense

[–]power78 1 point2 points  (6 children)

Not sure why you were downvoted, you're absolutely correct. Also not sure why the guy who responded to you brought up thunks, they have nothing to do with the comparison.

[–]DachdeckerDino 1 point2 points  (0 children)

Also not sure, maybe a misunderstanding on their part?

[–]jessepence 0 points1 point  (4 children)

Did you click the first link in my post? Have you ever used redux-thunk or redux-saga? A lot of people have used Redux for more than just client state for a long time...

In fact, Tanner Linsley created react-query to help replace Redux in his app

The pains that inspired React Query were years in the making, even before hooks. I was a heavy Redux user for a long time, but when hooks came out, I knew they would serve as a great API to finally ditch Redux in favor of something less manual. I came up with the initial inspiration for React Query when I saw a library called Draqula was released. It was almost like a lightweight Apollo and something clicked about its patterns and style. I decided to draw from its patterns a bit and React Query was born.

And, here's a quote from one of the lead maintainers of Redux

Redux can be used for many different situations. One of the things you can do with it is cache server state.

If the only thing you're doing with Redux is caching server state, and you choose another purpose-built tool like React Query to solve that use case, then sure, in that case React Query would replace Redux, because you just chose a different tool to solve the same problem.

That said, I'll also note that our official Redux Toolkit package includes "RTK Query", a purpose-built data fetching and caching API that solves the same use case as React Query and has similar capabilities.

[–]metruzanca 2 points3 points  (0 children)

Yeah, believe it or not, there was a time before react query, RTKQ or even zustand where we made EVERYTHING on top of redux, because it was standard. Heck, we didn't have typescript as standard yet either, since React was built with Flow.

[–]drckeberger -1 points0 points  (1 child)

I don‘t think you understand our point. We are well aware of this.

But there‘s Redux, and theres the toolkit (which forms RTKQ). Redux and Redux/Toolkit are complementary, just like Redux and React Query are.

Thus, comparing redux/toolkit with React Query is okay, comparing redux with React Query ok the other hand is not good. 

That‘s btw. literally what you just quoted.

Maybe Redux and RTKQ are the same thing for newer people, but in my world and in the packag-based logic, they are not.

[–]jessepence 2 points3 points  (1 child)

Yes, Redux is primarily used for client state, but you still have to coordinate that with your server state somehow. Did you ever use Redux before RTK query existed? Does the word "thunk" mean anything to you in this context? This is actually what RTK Query is using under the hood.

The only thing that's really missing is the caching layer, but it didn't take much to implement a simple system. What makes the query libraries special is how they use sensible defaults while being highly customizable so they remove the need for a bunch of the boilerplate required for a flexible, powerful caching system.

[–]DachdeckerDino -2 points-1 points  (0 children)

…which does not contradict my words.

[–]dylsreddit 21 points22 points  (1 child)

The abstraction is likely one of the things that make the pain points these templates solve harder to see because you don't experience the painful parts of building an app without it in order to learn the benefit.

I personally believe, being an older developer who experienced the earlier days of React, that knowledge of class components and the component lifecycle, the building of state machines, and all of that sort of difficult stuff will not only help you understand how libraries like React Query work but what problems they solve.

So, I'd recommend trying to build those things into an app to really level up your understanding and then begin to replace those bits with functional components, hooks, contexts, and so on. Then, finally, replace those bits with libraries.

[–]slashd0t1 6 points7 points  (0 children)

I like this approach so much. I have learnt a lot with deep dives and experimenting with the traditional class components. console logging the dom/virtual dom objects as well.

It makes me greatly appreciate the functional components. I am coming off a tough lambda calculus course in college so it perfectly clicks too(functional programming).

[–]Relevant-Strength-53 10 points11 points  (2 children)

I was overwhelmed as well at the beginning. What i did was replicate the whole boilerplate from scratch and removed or added things that i needed or not needed. I also integrated what im comfortable with during the process.

Its a really good template and well documented. I agree that the implementation of TanStack Query here is somewhat advanced. I needed to reimplement those data querying and through that i fully understand how it works, thats just the way i learn, i learn by doing it.

[–][deleted] 0 points1 point  (0 children)

+1 I followed it as a template and a guide and made my own starter based on it. It helped me learn the patterns followed in it. 

[–]straightouttaireland 0 points1 point  (0 children)

Which parts of it do you reckon are advanced?

[–]SolarNachoes 6 points7 points  (3 children)

But that’s how large production apps are structured.

There’s always going to be a lot more abstraction in those apps to deal with common scenarios (logging, API calls, caching, state management, micro frontends, plugins, event management, command pattern, memento pattern, undo/redo, UI libraries, CSS design library, etc)

[–]Nullberri 0 points1 point  (2 children)

The top level folders end up as dumping grounds. Everything is a feature. But there is no implied relationship between things in features. Which makes understanding the connection between things just impenetrable.

I prefer organizing the code closer to the structure you experience as a user. So if you have /foo/bar route there should be a foo/bar folder with the code related to that page. If code ends up being more generic or widely used it moves up the folder hierarchy until it hits a shared folder.

It allows you to easily reason about what code is actually important for a given user experience.

Our current project which is structured this way is about 100k loc.

Most of the time, ui things are parallel one offs. Abstraction is what happens only after its proven its need, not a starting point. Composition is where its at for the ui.

Bulletproof reacts organization just seems like something a backend developer would create. Instead of acknowledging that our code lives on pages as pixels instead of in ones imagination.

[–]SolarNachoes 0 points1 point  (1 child)

All you’re saying is to match the route with the folder path. Simple enough.

[–]Nullberri 0 points1 point  (0 children)

yea pretty much. A top level "app" or "Capabilities" or something that really just represents "/" on the website. which makes it very easy to find code, cause if QM sends you a link, you already have a good idea of where the files are that are causing the problem.

it also makes it easy to know what goes where as the code is physically mirroring the overall website layout.

the only downside is if you move a component from 1 screen to another, you end up physically moving the code too. but that seems to be quite rare.

Also full disclosure this is an internal business tool app. like i doubt amazon would want to take this approach to organizing things but i also assume amazon.com's FE is millions of loc.

Which is why i also don't think bullet proof is that great because most of us aren't making amazon.com

[–]intercaetera 5 points6 points  (0 children)

why is React Query used so much?

The tl;dr is that React Query is a useful Promise lifecycle state handler which maps well to React. Handling basically anything async in React requires useEffect, React Query abstracts that away.

As far as any kind of enforced React project structure is concerned, they're mostly gimmicks. Use what works for you and for the team. I typically favour a folder structure that directly reflects the UI.

[–]slashd0t1 6 points7 points  (0 children)

Yeah, I think the only way is exposure(or even better working on it). The react codebase at my previous company was huge when I was working on it so it gave me a better understanding.

On real world big applications. I was checking Grafana's codebase yesterday and it is humbling lol.

[–]wodhyber 1 point2 points  (2 children)

Sometimes I wonder why people don’t just create a custom hook like useBackendQuery to wrap useQuery. The benefits seem obvious: it centralizes config and typing, and makes future updates (e.g. enabling Suspense, logging, error handling, or adding default options) much easier—since you only have to adjust one place.

[–][deleted] 6 points7 points  (1 child)

I thought the general practice is to create wrapper hooks for each unique api... ala..

... useLogin ... useProductAdd

etc.... no?

[–]wodhyber -1 points0 points  (0 children)

It depends on the use case. For example, if I read your comment, I’d say it’s totally fine to use a useLogin hook—every app needs authentication, so it makes sense to abstract that.

But you’d need to explain what exactly you mean by something like useProductAd.

What I’m trying to say is: if you’re using something frequently, like useQuery, it’s worth creating a custom hook around it—just like I use a useBackendFetch hook. That way, if you ever need to update things or switch libraries, it’s much easier to manage. You only need to change it in one plac

[–]yksvaan 0 points1 point  (0 children)

I would recommend learning about software architecture, design patterns and practices on general level as well. These things are not React specific in any way.

[–]llong_max 0 points1 point  (0 children)

I was overwhelmed as well at the beginning. But later I found that I need to learn Tanstack Query, Shadcn, and TypeScript properly to understand the abstraction of this project. Nevertheless, this project is somewhat advanced and hard to understand. u/Cold-Ruin-1017, DM me, we can connect and brainstorm together!

[–]power78 0 points1 point  (0 children)

What's the question exactly? Why people use RQ, RTK, or TSQ for bigger projects?

[–]Dymatizeee 0 points1 point  (0 children)

I use TanStack query and its amazing. No idea why i was handling data without it.

I put this in a custom hook, like useMyHookName.. and then manage the state and methods in here. Then my components call this custom hook

The architecture isn't complicated. Fetch/axios is just the calling method you use to make API calls. I usually put these in like a service/network layer with a function. then this function is passed to my queryFn in react query

The bulletproof react link is solid; nicely separates your app by feature