-
-
Notifications
You must be signed in to change notification settings - Fork 8.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
markRaw / shallowRef is not respected by deep watch #2380
Comments
Edit: Oh I see you came to the same conclusion ... 😊 That's because My first instinct is to rate this s bug: But thinking about it, one could argue that it should traverse them as a raw object could still contain nested reactive objects. If it didn't, and a raw object contains a reactive opbject, it's mutation could not be observed by So we consider it a bug, the fix is easy. Edit: Not that easy for If we don't, then we need to discuss wether we should have a second way of a deep watch that does skip raw-marked objects, like deep: 'shallow' or something? |
Thanks so much @LinusBorg . You have saved me several times at Vue 2 before and now Vue 3. Yes, I have thought that there may be some cases that a raw object contains a reactive object. I think you are right that Vue should take care those nested reactive object mutation inside
this statement should not only for |
a raw object is not reactive, and can't be observed (that's why you marked it raw, right?). Strict mode just watches the state tree for changes to reactive objects, and then warns about them. changes to nonreactive objects can't be observed and consequently, can't be warned about. Vuex should likely add an option to just wrap the exposed |
That's exactly what I would argue. I may create a For me the semantics of "shallow" apply to automatic proxifying (proxification?) of the whole object graph. They are unrelated to observation itself. Consider that a
Someone who's doing advanced stuff may use That kind of scenarios would be totally broken if the change suggest here is done. |
should there be |
I wonder how that would work. By essence |
BTW I'm not sure what is the exact use case here. If you want something more specialized, e.g. maybe just 1 or 2 level deep, or to any other arbitrary condition (e.g. the object is marked as raw), then I think the proper way is to do your own traversal and not rely on the built-in deep. It's easy to do today in user-land and it's more healthy for Vue to keep general, intuitive semantics for the built-in functions. |
@jods4 Can you provide a hint how to implement custom traversal? Background: I intenden to use |
@waruyama There are a few quirks. 👉 I feel like there's one option missing from the watch API here. When your source is a reactive object or array it's hardcoded to always be observed deeply. Seems to me it should be possible to watch shallowly if you don't ask for 👉 But you can work around things by fiddling with the // If by "the entries in the array change" you mean: adding/removing/assigning the array itself, this should work:
watch(
() => {
array.forEach(() => {}); // read all array entries
return {}; // return a new instance as the "value" so that it's different and callback runs
},
callback);
// If you mean the points themselves can mutate and you want to shallowly observe them:
```js
watch(
() => {
array.forEach(Object.entries); // read all properties of every point
return {}; // as before: new "value" each time something changes
},
callback); That's the gist of it, you can tweak the source function in many ways. |
Version
3.0.0
Reproduction link
https://github.com/mannok/vuex-traverse
Steps to reproduce
6-a. You will see a log msg
THIS MSG IS SHOWN WHEN IT WAS SET ON STATE!
even I have marked raw to the object. i.e. log msg shouldn't be shown, asmarkRaw(obj)
's properties shouldn't be traversed down when it was set to state.6-b. Comment line 30 and comment line 31 and refresh the browser again. You will no longer see the log msg as Vue won't traverse down
markRaw(obj)
.What is expected?
When I call
markRaw()
for any object. It shouldn't be traversed in any scenario. (Vue or Vuex)What is actually happening?
It is acutally traversing when the marked raw object is set on Vuex state.
Maybe you will think this problem doesn't matter, but currently I am using a big library which comprises of many complex object. I just want to store them inside state as raw object / shallowRef, but I have no way to do it... It keeps traversing deeply for me and the performance is really bad... Please help me out! Thanks in advance!
UPDATE
Seems that my problem is that I have no way to stop Vuex to run
traverse()
insidevue\dist\vue.runtime.global.js
. FYR:The text was updated successfully, but these errors were encountered: