vuejs / rfcs

RFCs for substantial changes / feature additions to Vue core
4.86k stars 548 forks source link

Advise against Flux, Vuex #240

Closed Madyuskin closed 3 years ago

Madyuskin commented 3 years ago

From https://vuex.vuejs.org/#when-should-i-use-it

If you've never built a large-scale SPA and jump right into Vuex, it may feel verbose and daunting. That's perfectly normal - if your app is simple, you will most likely be fine without Vuex. A simple store pattern (opens new window)may be all you need. But if you are building a medium-to-large-scale SPA, chances are you have run into situations that make you think about how to better handle state outside of your Vue components, and Vuex will be the natural next step for you.

That is wrong and misleading. Every dev team is sure they are going big. Vue is already perfect regardless of the size of an app. Adding Vuex is just harmful. I wrote an article explaining why Flux has nothing to do with Vue:

https://medium.com/@madyuskin/flux-vuex-are-wrong-and-outdated-61438de7c512

I am the author. The same username as on GitHub, I can text you.

leopiccionia commented 3 years ago

I think that labeling something upfront "wrong and harmful" may be counter-productive to the debate. "Considered Harmful" Essays Considered Harmful.

How can Vuetify thrive without Flux if the latter is so indispensable?

Why should it care about global state management, that's, by definition, orthogonal to component composition?

For component composition, props, events, slots, provide and inject may be enough. You probably don't need Vuex for that.

Never used on the server side with Node.js even without immutability

Flux-like patterns are for application-level state management. In a server, you typically want the opposite: the state to be short-lived and isolated by process/request. And most servers already provide mechanisms to encapsulate and pass state, like middlewares.

It came from React. It didn’t originate in Vue. It is already enough to suspect that something is not right. Flux, Redux were developed because of React’s poor support of immutability.

It sounds like a genetic fallacy for me. Could you elaborate?

Now for the most interesting part:

Vue supports immutability for an object reference out of the box

By "immutability for an object reference", you mean object mutability detection, that's what React's diff algorithm actually doesn't handle well.

That’s why they require you to normalize your state as a SQL database.

The source you're probably quoting recommends normalization because of "nested or relational" data.

For typical nested data, normalization is usually overkill. There are Immer and dozens of other libraries that present solutions for this problem while keeping React/Redux constraints.

Relational data, though, sometimes contain many-to-many dependencies. In those cases, normalization is a better investment. Normal forms were introduced in 1970 as a method for avoiding data inconsistencies (actual bugs) and duplication. You can obviously handle all cases manually instead of normalizing the data, but bugs may ensue.

Normalizing your data is such a good advice that it appears even outside of the relational databases realm, like in MongoDB and Firebase, just to cite two.

It's also important to emphasize that neither Redux nor Vuex strictly require this type of normalization, they're just a mechanism to enforce data consistency.

Theorically, as Vue's diff algorithm detect object mutation (differently from React), you could structure your data to use circular objects (never tried it, so I don't know if Vue is happy with that). But it's still a type of normalization, just different -- and probably harder to enforce. And, differently from "foreign key" normalization, it needs to be made on client-side.

  1. No v-model support
  2. Tons of boilerplate. Writing for the sake of writing. Zero commercial value. Wasted time and energy.

Pathify solves these issues very well, while allowing you to use the usual Vuex syntax side-by-side.


I'm not disagreeing that Vuex is not always needed. I have worked on many Vue projects that used it, and many that don't.

Vuex greatly helped me maintain and debug code in the past, but I'm glad that the Vue team has some plans about improving Vuex in the next months.

Madyuskin commented 3 years ago

Thank you @leopiccionia for your elaborate answer. I am preparing my answer. It might take 2 days.

kiaking commented 3 years ago

@Madyuskin I believe it would be better if you could clarify the purpose of this issue 👀 . What is your actual suggestion here? What is the exact thing that you wanna change, add, remove? from what, where, and how?

Madyuskin commented 3 years ago

@leopiccionia

Why should it care about global state management, that's, by definition, orthogonal to component composition?

I mentioned the absence of Flux in UI widgets in "Why Flux looks suspicious", not in "Why Flux is wrong". If something claims to be:

predictable, centralized, debuggable, flexible, simple, opinionated, powerful, effective

to be indispensable, and is as popular among developers as Flux, Redux, then I expect such product to be universal. For example, it is just an example, don't come to any conclusion:

export default {
  created() {
    this.store = new Vuex.Store({
      ...
    })
  }
}

Or be built-in. I am glad Flux is not.

What is actually Flux?

From https://redux.js.org, the advantages are:

  1. Consistent behavior
  2. Easy to test
  3. Undo/redo
  4. State persistence
  5. Debuggable
    1. When, where, why, and how your application's state changed
    2. Time-travel debugging
  6. Works with any UI layer

All of the above is a result of storing data in global state. It is global state vs local state. You don't need Flux for this. There is only one advantage - ultimate debugging. But why do we need debugging, logging for each a = b, a.push(b), etc? ALL SOFTWARE except some apps that use Flux are written without this level of debugging - operation systems, databases, compilers, drivers, antiviruses, games, everything!

Normalizing your data is such a good advice

Yes, you are right! Data should always be normalized. But do we need Flux for this? No! So, what is actually Flux?

const counterSlice = createSlice({
  name: 'counter',
  initialState: 0,
  reducers: {
    increment: state => state + 1
  }
})

Looks similar to

class Counter {
  private int state = 0;
  public void increment() {
    this.state++;
  }
}

Firstly, slice and class are incomparable. Moreover, there is no slice in Vuex. Secondly, Flux is a wrap with no purpose. That's why they achieved ultimate debugging and ultimate boilerplate. What is the point of mapping every single method from Array.prototype.* and then repeat it for a new property? If I were paid for the number of lines in code, then OK, I would agree, yeah. And they attributed to a wrap the advantages of normalization and the advantages of keeping everything in global state.

they're just a mechanism to enforce data consistency.

You are right! Because of global state and normalization. You don't need Flux for this.

Pathify solves these issues very well, while allowing you to use the usual Vuex syntax side-by-side.

Google: site:vuejs.org Pathify Any page except forum.vuejs.org and news.vuejs.org? And you probably already know my answers:

  1. No Vuex - no problems

  2. Vuex Pathify, Pathify for Vuex Pathify, Pathify for Pathify for Vuex Pathify,...

    The roadmap of Vuex

    From https://vuex.vuejs.org/#when-should-i-use-it

    and Vuex will be the natural next step for you.

  3. Overall, Vuex is less strict than Redux

  4. Unlike Redux, actions don't belong to a property

  5. Mutations will be removed in Vuex 5

  6. ...

You are naturally stepping away from Flux.

Conclusion

From https://vuex.vuejs.org/#when-should-i-use-it

if your app is simple, you will most likely be fine without Vuex.

Every dev team is sure they are going big. No money paid for little-to-no work. I think that labeling everyone's apps without Vuex not "fine" upfront may be counter-productive to the project. "Considered Harmful" Essays Considered Harmful. That is exactly what happened to me and my team as we had to rewrite our apps without Vuex. I believe this.$root (not even this.$root.$data) is all that we need.

Madyuskin commented 3 years ago

@DavidMulder0 disliked my issue and commented on Medium:

Do I agree that redux/flux/vuex/etc. aren't always needed? Absolutely. But I also have to say I think it's very misguided to attack it one sidedly. It really does depend on the complexity of the application. Right now I am working on a text editor that uses something like the flux/redux/vuex pattern and it just makes a lot of sense (the 'document' that's getting edited affects the UI in a bunch of different places) and that's not even touching upon how valuable centralized state is for things like 'undo'/'redo' actions or restore functionality when the user leaves an app, but at the same time there is no value at all for certain other applications or just websites. The simplest question to ask yourself I believe is: "Is my application going to have a state that affects things in completely different places in the DOM". In the case of a UI component library this is by definition not the case, so for something like vuetify it doesn't make sense. For something like a complex dynamic batch management interface it might however make the code super easy and clean.

No comments. People just don't know there are options. They are denied even a try.

DavidMulder0 commented 3 years ago

@Madyuskin The confused reaction just expressed that I am utterly confused by what you're trying to do here. A confused reaction isn't the same thing as a downvote, it's just that none of this makes any sense here. You have been talking with and to yourself for nearly two weeks now. I was fascinated by someone 'attacking' a library I am using, as I enjoy seeing posts of that nature, so I replied to the post. You seemed to be talking about the pattern, but then you attack people for talking about the pattern rather than the libraries, you mix up flux and redux all over your post and that doesn't even touch upon why in the world you would copy a post from Medium to here... maybe the fact that I replied on Medium should have rang a bell that that's where the 'conversation' belonged.

Madyuskin commented 3 years ago

https://twitter.com/dan_abramov/status/1191495127358935040

Madyuskin commented 3 years ago

With Flux, Vuex comes access restriction — the state can only be changed via the methods. It is useful if we change global state from completely different places. But, almost all time we use and change a part of global state, for example, a Vuex module from the same place.

/close