vuejs / vuex

🗃️ Centralized State Management for Vue.js.
https://vuex.vuejs.org
MIT License
28.41k stars 9.57k forks source link

Immutable references state properties should NOT warn of `do not mutate vuex store state outside mutation handlers.` #1926

Open LifeIsStrange opened 3 years ago

LifeIsStrange commented 3 years ago

What problem does this feature solve?

In a lot of contexts, we want to store reference of objects in the store that come from a library. This means that the reference come from outside the store and is managed (mutated) outside of the store too.

Vuex will by default, rightfully throw a warning because the object is mutated oustide of the store mutations. However in some cases it is useful to store such references in the stores as immutable references, in order to persists them and to use them through getters and actions. The warning should not be thrown IF and only IF the reference is Immutable. The only known way of ensuring this is to wrap the reference with this Type:

type Immutable<T> = {
  readonly [K in keyof T]: Immutable<T[K]>;
};

for example the state could have a tiptap Editor reference:

editor!: Immutable<Editor> = getTipTapEditorInstance();

Where the Editor properties setting is managed by the library. Which is a much needed pattern.

What does the proposed API look like?

Vuex needs either to propose an Annotation that we would put above the immutable reference declaration in order to silence the warning just for this reference. OR to detect at runtime to not throw the warning if all keys of the object are immutable/const OR to detect if the reference is wrapped by the type Immutable, type which could be provided by Vuex or even Vue.ts because it is generally useful

kiaking commented 3 years ago

Good point. This is not that easy thing to fix, but I get your point. By design, Vuex state is meant to be plain object, and wasn't design to be mutated by the stored object. But, I can see there're use cases where this is useful.

We should rethink how we manage these situations in next version of Vuex.

Mean while, you could suppress the warning by setting strict option to false I believe.

const store = new Vuex.Store({
  strict: false
})
franzliedke commented 8 months ago

Maybe markRaw() could be used to mark such references that should not be watched for mutations?