2 ms·
> Sure, global variables make debugging difficult when you don't know which function changed them where and when and why. But that doesn't happen if you keep yo
by kerkeslager 8y ago
> Sure, global variables make debugging difficult when you don't know which function changed them where and when and why. But that doesn't happen if you keep your functions pure and only make changes from within reducers – at least that's my experience.
Sticking to reducers IS a good idea and it does make things a bit better. The problem with global state goes deeper than that, though.
Often, as you learn about the structure of the data, it becomes useful to change how the data is structured and stored. In global state, you can change that in reducers, sure, but then all the places that render that data have to be updated. You don't have the option to represent the same data in different ways that might be more suitable for different parts of the application. You either have to change them all at once, or synchronize a bunch of states that really contain the same data (which is even worse).
With independent components, you do spend some time synchronizing data across components, but each component has the option of how to represent its data internally, so the effects of changing data representation in one area are usually very local, and each area of the code gets to represent the data in a way that's reasonable for what it's doing.
I'll also add that with independent components, you sometimes get components whose only real job is to manage data. That's actually sort of like a Redux! But you can spin up multiples of them without having to manage an array, and compose them or even nest them without issues.
> (Boilerplate, yes, Redux adds that. But at least it's all in one place, and not scattered throughout your app.)
To be clear, I don't really care about boilerplate. It's easy to generate that stuff, but even if you write it by hand it's faster than debugging implicit, hidden complexity. Boilerplate ISN'T the problem with Redux, as far as I'm concerned.
- poink 8y agoIf you're giving me the choice between dealing with this: > Often, as you learn about the structure of the data, it becomes useful to change how the data is structured and stored. In global state, you can change that in reducers, sure, but then all the places that render that data have to be updated. You don't have the option to represent the same data in different ways that might be more suitable for different parts of the application. You either have to change them all at once, or synchronize a bunch of states that really contain the same data (which is even worse). or this: > With independent components, you do spend some time synchronizing data across components I'm not even hesitating before I choose the first option. My editor, static analysis, and the mystical art of the function can give me all sorts of help with the first problem. Good luck with those sync bugs.
- kerkeslager 8y agoYou selectively quoted me, ignoring where I explained that synchronization isn't as big of a problem with passing properties into components. I already addressed your concern. Don't selectively quote me, it's rude and just shows you aren't following the conversation. Futher, Redux doesn't solve synchronization issues in situations where you can't represent the data the same way. In the most complicated situations, it actually exacerbates the issue because it separates the data from the components that use it, making static analysis tools unable to see how your data changes might break the components. This also goes to show you didn't even understand the part of what I said that you selectively quoted, since I already said this. > I'm not even hesitating before I choose the first option. Perhaps if you hesitated a bit more, you could use that time to read all of the options and understand them.
- poink 8y agoI read the thread. You hand-waved away a non-trivial problem by "explaining" properties are a thing. Thanks, bud. I'm sorry I didn't cite your favorite source to your satisfaction, but I quoted the relevant parts of the post I replied to. > Futher, Redux doesn't solve synchronization issues in situations where you can't represent the data the same way. It's kind of the whole Redux philosophy that you won't do that. It's in the FAQ. There's no "can't". You're never forced to keep duplicate data in your store.
- kerkeslager 8y agoBut, in a project of any significant complexity, you will represent the data in different formats, because transforming data into different formats is one of the main functions of software. Relying on a framework that assumes you won't do something that you will do is a Very Bad Idea.
- poink 8y agoIt's almost like `mapStateToProps` is a thing and Dan Abramov has built a web app before. You have to store and transform your data in a normalized form, but you can consume it however you want. Restrictions are the price of solving hard problems (even if you don't want to admit they're hard) in a deterministic fashion.
- pault 8y agoIt's generally considered a best practice to use pure selector functions in your UI components so the only place in your application that references the actual data structure is the root selector that pulls data out of the state tree. I personally try to structure my selectors so that any refactoring only requires changing a single line of code.
- kerkeslager 8y agoOkay, so the only way it's actually possible to have any refactoring of your data structures require only changing one selector is that you've got a single selector for literally every piece of data in your system, at which point you've had to manually flatten everything out into a bunch of selectors, and lost all the benefits of being able to read a structured chunk of data. If you actually do that (which I don't think most projects do fastidiously) you're creating a lot of boilerplate, again to solve a problem which was created because you decided to use global state in the first place. I'm not saying there aren't solutions to the problems I'm bringing up. I'm saying you don't have to solve them in the first place if you don't bring in Redux.
- pault 8y agoNot at all; you can write selectors that return a branch of your state tree, and you can generally tell where the line should be (user makes more sense than userName and userEmail). You keep saying that you won't have these problems if you don't use redux, but I am arguing that _you do have these problems_, you're just creating ad-hoc solutions for everything that you would use redux for, except those solutions are sprinkled into your UI components in a way that makes them full of mutable state that is impossible to test and a constant source of bugs. Note that I have already agreed that there is a scale where redux is overkill and creates more problems than it solves. Once your app has a few dozen components it's time to start thinking about another layer of abstraction.
- kerkeslager 8y ago> Not at all; you can write selectors that return a branch of your state tree, and you can generally tell where the line should be (user makes more sense than userName and userEmail). And then you're right back to any component that uses User being tightly coupled to the structure of the User, without any of the syntactic cues that allow you and your static tooling to connect the two. > except those solutions are sprinkled into your UI components in a way that makes them full of mutable state that is impossible to test and a constant source of bugs. That's not the case: 1. There's nothing preventing you from treating components as a pure function of their props. 2. At the top level, it's necessary to have some mutable state, but I'm not sure where you get the idea that this isn't testable. Redux doesn't remove mutable state: all redux is doing is a big complicated version of newState = pureFunction(oldState) which is perfectly possible to do using Vanilla JS functions.