4 ms·
The most common mistake I see is putting data fetching in the view layer. React hooks caused this because by default there’s no sensible place to fetch data.
by ibash 2y ago
The most common mistake I see is putting data fetching in the view layer.
React hooks caused this because by default there’s no sensible place to fetch data.
So unless you know ahead of time, any complex single page ends up with complex and hard to track network requests.
The solution is really simple: pull data out of the view layer and make it a first class citizen.
—
An exercise: imagine you’re building a tui instead of a web app, but you’re forced to use the exact same code for app state and data fetching… what would that code look like?
- boredtofears 2y agoReact has always just been the view layer. I'm not sure how hooks made the situation any worse, you're just using a hook (usually useEffect) instead of a class component method or componentDidMount. I don't understand what it means to "pull data out of the view layer and make it a first class citizen". If you're writing a React app, you are building a UI and will need to handle data in your view layer somewhere. You either hand-off that works to a library like Tanstack Query or you manage it yourself.
- wildrhythms 2y agoContrast to Angular which has a 'services' concept where this data fetching logic can live happily divorced from the view layer. https://v17.angular.io/guide/architecture-services https://v17.angular.io/guide/architecture-services
- branko_d 2y agoThe original promise of React was: UI = f(state) The problems come when you modify state in response to rendering the UI. This seems deceptively natural (and in fact seems encouraged by on-line tutorials), but leads to "spaghetti fetching" when composing components together - it creates a "feedback loop" that modifies state just because some component happens to mount, which can then modify state further, then cause further mounting/fetching etc... A better approach is to treat fetching as an explicit state change. If user clicks on a button, you do the fetch and modify the state. If that causes some components to be mounted - so be it, but does not cascade any further.
- postalrat 2y agoDid the original react only support stateless components?
- aatd86 2y ago>The problems come when you modify state in response to rendering the UI Yeah don't do that. Rendering shouldn't have such side-effects. Navigation might, but that's not rendering. Is it a common mistake with React?
- boredtofears 2y agoYes, that's right. The official React docs explain this pretty clearly.
- kherud 2y agoLet's say you want to show a modal, which fetches some data and modifies the state. Based on this, new children are rendered which again fetch state. The problem of "spaghetti fetching" becomes worse the more levels of recursive fetching there are. If I understand you correctly, you argue for fetching all data upfront, and then rendering the modal and all its children all at once. This way you ensure "UI = f(state)" by removing side effects from "f". On the other hand, I can also see some drawbacks: 1. This goes against the idea of fetching data close to where it's used, basically promoting modularization. 2. From the POV of the children, you have to backtrack where their data are coming from. 3. If components always use the same data, you have to duplicate fetching their data everywhere you want to use them. 4. You can't partially show children, but have to wait for everyone to have their data before rendering them. I feel like there are trade-offs to be made here.
- wooly_bully 2y agoThe sensible route to this today is to use a query client, IMO: tanstack, rtk query, apollo, etc. It prevents the umpteenth reinvention of an incomplete fetch state machine, which is probably the number one most consistent frontend bug I encounter.