News for hackers. Stuff that matters.
Re:Vue.js: the good, the meh, and the ugly by _bxg1 on Thursday July 05, 2018 @06:52PM (#17467545)
Well because the UI isn't just a function of state, it's also a function of those actions (the actions have to literally be passed in to the rendering function). So there's bi-directional coupling between the UI code and the Store (the UI code renders from the state, and passes messages back to the store).

Also, conceptually, you often have a lot of state that's very directly concerned with and specific to the UI, and isn't just idyllic, agnostic "data". Things like "is this menu open or closed?" and "what's the current string value of this input (which isn't meaningful until the form is submitted)?" In Flux, those things tend to add a ton of boilerplate in terms of change actions, and split tightly-related concerns into separate corners of the codebase (if I remove this menu component I have to remove its open/closed state variable and the corresponding action).

To be sure, there's not really a great way to decouple things in the reactive architecture. I personally lean towards stateful components that are decoupled at their boundaries instead, which does carry its own downsides. The only solution I've ever seen that truly felt right was two-way databinding, which Vue (sort of) still has, but which has fallen out of fashion in general because it requires "magic" and because it tends to come with performance costs.

Re:Vue.js: the good, the meh, and the ugly by shados on Thursday July 05, 2018 @10:20PM (#17468424)
> Also, conceptually, you often have a lot of state that's very directly concerned with and specific to the UI, and isn't just idyllic, agnostic "data". Things like "is this menu open or closed?

The entire UI is specific to the UI. Trying to separate "entities" or "server data" from "UI concerns" is IMO a waste of time and just confusing.

At the end of the day, you have a state tree, and you project it to a UI. Where that data comes from and what it represents doesn't really matter. Events in the UI generate an log that can get folded into new state to then be projected again. These events could be generated by a button being clicked, or an XHR request completing, but that doesn't change the nature of the payload.

One important thing though, in most of these models, the state shouldn't be "is this menu open or closed". It should be "Is the user focused on an arbitrary task or not". The menu being open or closed is a projection of that. This way when your designer comes and says "No, this thing shouldn't be a dropdown menu anymore, it should be a modal", you don't feel the need to rename your arbitraryMenuOpen: true state key to arbitraryModalOpen: true instead. Saves a lot of time.

Elm is a pretty good example of how all of this works. Its fairly different from Redux and co (even though it inspired it a lot), but its interesting to see how all of these things absolutely can work. They get messy when retrofit into React and JavaScript, but it's not an issue with the concept, just the implementation.

Re:Vue.js: the good, the meh, and the ugly by _bxg1 on Thursday July 05, 2018 @11:20PM (#17468615)
That level of abstraction sounds nice, but isn't really practical. A dropdown menu and a modal have wildly different use cases and relationships with the rest of the app. The only way the former would directly translate to the latter is if the latter contains nothing but a set of radio buttons, in which case you should hire a new designer.

In fact, the reason we have the particular toolbox of standard GUI elements that we have these days is precisely because they serve different use-cases. Each serves a particular one, and the reason it's survived is because it isn't made redundant by any of the others.

Re:Vue.js: the good, the meh, and the ugly by shados on Friday July 06, 2018 @11:21AM (#17472141)
> That level of abstraction sounds nice, but isn't really practical

The only thing not practical about it is that in these days and age, the amount of people with data modeling experience is low. But it totally does work in practice and is, IMO, the only way to really be productive with Redux. Otherwise any change you make or any new feature requires modifying components, actions, AND reducers. At that point you're just doing 3 times the work for everything.

Re:Vue.js: the good, the meh, and the ugly by danwilsonthomas on Thursday July 05, 2018 @08:37PM (#17468064)
I've seen this idea a lot from members of my team that when you use a state management library then absolutely everything has to go through that state management library. This results in some of that pain you describe with state that's specific to the UI. If you're still working with React, try keeping that menu or input state in the component with setState instead of putting it in the global state store. I've found that simple change to clarify our projects immensely by cutting out lots of unnecessary code and highlighting what state is actually important to the functioning of the application.
Re:Vue.js: the good, the meh, and the ugly by acemarke on Thursday July 05, 2018 @08:44PM (#17468097)
Yep, this is exactly why the Redux FAQ has a section with rules of thumb for deciding whether a particular value should go in Redux or not:

https://redux.js.org/faq/organizing-state#do-i-have-to-put-a...

Re:Vue.js: the good, the meh, and the ugly by _bxg1 on Friday July 06, 2018 @12:26AM (#17468822)
That seems like a good approach. Still, it doesn't seem like the rendering code or the Store code could ever really be worked with in isolation. As I said above, picking a coupling boundary is like picking a poison. They all seem to suck for different reasons; I just personally tend to choose component boundaries.
Re:Vue.js: the good, the meh, and the ugly by aylmao on Friday July 06, 2018 @03:36AM (#17469660)
I'd recommend starting with the application as an abstract entity: start with the state and not think about the UI. Once you build a data-model and action scheme from there, working a de-coupled UI is usually simpler.
Re:Vue.js: the good, the meh, and the ugly by aylmao on Friday July 06, 2018 @03:31AM (#17469645)
> Well because the UI isn't just a function of state, it's also a function of those actions (the actions have to literally be passed in to the rendering function).

Wait, they don't though. That's the whole point of functional components. They are of the form:

    const Component = (props) => <JSX />
Where are said "literally passed" actions here?

> So there's bi-directional coupling between the UI code and the Store (the UI code renders from the state, and passes messages back to the store).

This isn't bi-directional binding. state determining UI, UI sending queued actions and actions determining state is one-way data flow. Bi-directional coupling would be tying a reference in the state to a UI element.

> Also, conceptually, you often have a lot of state that's very directly concerned with and specific to the UI, and isn't just idyllic, agnostic "data". Things like "is this menu open or closed?" and "what's the current string value of this input (which isn't meaningful until the form is submitted)?"

This is architectural, and is why components have their own state. Its up to you wether you want to keep this as application state or local volatile state.

> In Flux, those things tend to add a ton of boilerplate in terms of change actions, and split tightly-related concerns into separate corners of the codebase (if I remove this menu component I have to remove its open/closed state variable and the corresponding action).

Which is why I don't put it in the main application state (:

> To be sure, there's not really a great way to decouple things in the reactive architecture.

I mean, not if you're dumping everything on your application state, no.

> I personally lean towards stateful components that are decoupled at their boundaries instead, which does carry its own downsides.

Curious to learn what you mean by "decoupled at their boundaries". You mean components that are de-coupled from each other? You can make re-usable, functional or stateful components that are de-coupled from application state.

I think the main takeaway here is that not all state is the same, there's state that's part of your core application logic and state the component needs for its display only. Treating them as the same thing does limit the re-usability of your code and make dealing with your application state tedious.

> The only solution I've ever seen that truly felt right was two-way databinding, which Vue (sort of) still has...

There's other solutions (: I don't think Netflix, Facebook or AirBnB have all the state of their menus tied up with the state of their user data and and have all components be use-once because of that. Good state management can make things scale, and functional components very useful!

> but which has fallen out of fashion in general because it requires "magic" and because it tends to come with performance costs.

Yup. It's also hard to know where or how certain state is changing. It definitely allows you to build small applications very quickly, but it doesn't scale all that well.