4 ms·
I still find the whole subject so frustrating. Being a backend developer that has since out of necessity had to transfer to being a frontend-architect for a tea
by tunesmith 4y ago
I still find the whole subject so frustrating. Being a backend developer that has since out of necessity had to transfer to being a frontend-architect for a team of confused React developers, I'm struck with how the momentum of frontend development quickly leads to very complex state machines. Backend development hasn't tended to require this - you query information, perhaps you transform it, you return it. But with frontend state machines, you've got things that feel like global state sitting all over the place.
If the logged-in user is this or that and/or the component state is this or that then do this unless that, and if this part of the component changes/re-renders to be that, then refigure the entire state all over again so this or that can be adjusted if necessary...
I mean, I get it, basically any GUI is going to have matters like this. And I get that the idea is to work really hard to limit the contract of each sub-component so that it can feel pure and only be dependent on a limited number of parameters/properties coming in. After all, on the backend it's also easy for a bad programmer to write a function/method that accepts forty parameters and has horrendously complex logic inside.
But in practice, something about the product cycle and the feature cycle of React just makes it so easy to turn into a huge snarl really fast. I feel like I'm battling against the tide. Maybe it's just something specific to our team and I need everyone to just freeze until we get some better practices in place.
- dqpb 4y ago> Backend development hasn't tended to require this - you query information, perhaps you transform it, you return it. Maybe the backend of a crud app is fundamentally simpler than a user-facing UI.
- tunesmith 4y agoThat is one possible explanation, sure. But more than inherent complexity, it's also about whether there are sufficient guardrails and best practices in place to help manage that complexity.
- erikpukinskis 4y agoI’ll add to this, there are tough problems that we solve on the front end that the backend could solve, but backend developers run scared from. For example: most backends will let you query arbitrary data, but they won’t alert you when that query changes. So we solve this on the frontend (often laboriously, with spaghetti). IMO backend developers are often unwilling to do anything beyond CRUD… and specifically they are often unwilling to model the dynamics of a domain. They want to treat the domain as frozen in a moment of time. In general, I would love to see more backend developers be more ambitious about trying to see which jobs the frontend is doing that could be solved on the backend. I think that could distribute some of the workload more evenly, and give BE devs a taste of what that higher level of complexity looks like. Sometimes I think backend developers just write off hard problems that they could solve because “that’s a frontend concern”. It’s an easy excuse.
- hakfoo 4y agoThat's always something I've found weird. There are things that are "global state", at least in the sense that you're likely to care about them in a hundred disparate places. If you're writing a UI, odds are at some point you're going to want to see "current user ID", "language selection", etc. Why can't we just say "it's global" rather than doing all sorts of plumbing to pipe these details around the code base? I know we have stuff like contexts, but it feels a strange workaround, like someone saying "I'm on a diet, no sugar... but put 12 teaspoons of honey in my tea." I know that the standard line is that it's difficult to test globals, but maybe developing a better test mechanism is a more tractable problem than having to add extra infrastructure to reinvent globals.
- andrewstuart2 4y agoIt really should be global, if it's global state. Maybe not directly in the javascript global (window) context, but part of a shared singleton, in an obvious (or at least consistent) way, or similar. The simplest and most obvious pattern I've ever used was essentially an angularjs (1.x) directive that allowed templates to grab named references to services and directly reference that state. Mutations were also exposed on the services as plain old functions, and it all just kind of worked. Looking at a template, it was blatantly obvious where the data and methods came from. The two way binding just made it dead simple to grok what was going on once all the layers of abstraction (controllers in the AngularJS world) that might rename things or make up new clever abstractions were gone. I've built with React a half dozen times now, and I still haven't found anything that got me close to that level of simplicity. I'd say most of my experience has been that it's at least 10x more complex with all the gymnastics you have to do to keep the data flow unidirectional.
- bernawil 4y agoI think this is a bad take on an old premise. It's not that "global state is bad", rather, "global MUTABLE state is bad". Which is kind of right but for the wrong reasons. Truth is, "mutable state" is bad and "mutable global state" is even worse. That comes from the old times of OOP when people insisted in "encapsulating" state and relied on mutation. It's sort of a logical fallacy. How could global state be bad if reading from a database o an API is essentially that? The problem is mutation, that if global state is mutated somewhere, other places that read the same state don't know about it. Modern state managment instead is immutable and is not even an original idea of React. Redux was basically copied from Elm's state management.
- wonnage 4y agoSometimes the business logic just sucks and you have to deal with it. For logged in stuff in particular, it's easier IMO to fork entire pages/components completely instead of trying to make things handle both cases. You can always come back and refactor if it turns out the splitting was unnecessary, but it's really hard to go the other way.
- ironmagma 4y agoIf you have a good, generalizable alternative, maybe you should try turning it into a library. My feeling is that “database you can query” was the idea of Redux. It worked out all right, but the performance bottlenecks were kind of bad because everything that queried the store had to subscribe to every update and do some dirty check which eats up performance. The solution was to use Redux sparingly, preferring local state for things that need to be updated frequently, kind of like an L1 cache. But again, that leads to fragmentation. I think Recoil is supposed to fix this issue but I haven’t learned it yet.