Skip to content

Conversation

balint42
Copy link

@balint42 balint42 commented Apr 6, 2017

This is a proposal for extending the docs with detailed explanations about when props are reactive. It originated from the forum discussion created for this purpose.

Please review my points carefully and let me know about mistakes I have made or possible improvements to the content.

Copy link
Member

@kazupon kazupon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your feedback!
LGTM 👍

/ping @chrisvfritz @yyx990803
Please check it!

@kazupon kazupon requested review from yyx990803 and chrisvfritz April 7, 2017 02:50
@yyx990803
Copy link
Member

Thanks for the PR - however, I feel this isn't quite accurate and may actually cause more confusion...

This is what is actually happening:

  1. Prop bindings are always reactive when referenced inside render functions or templates.

  2. data is called only once without dependency collection. It's the initial state of your component. Props references inside data will not be registered as dependencies.

@balint42
Copy link
Author

balint42 commented Apr 7, 2017

@kazupon & @yyx990803 thanks for your feedback! @yyx990803 your points are very good of course, thanks for explaining! The question is whether we can improve the PR up to a point where it makes sense to everyone.

My motivation here stems from two observations:

  1. People seem to be associating the v-bind "dynamic" or "reactive" property binding with the data function reactively re-running - not a totally unreasonable assumption if you think about reactivity in the Meteor-verse
  2. People seem to be regularly in need of the pattern I am mentioning using watch: you want to init a data value with a property and want it to update from the property as it changes while also changing it inside the component (2 deps: internal & external; aka unidirectional interface; aka flux)

Is this worth explaining? How can we correct the PR, am I wrong assuming that if you save an Object by ref in data the templates where you use this data will reactively re-render?

@yyx990803
Copy link
Member

If you want the prop to be reactive why not just use it directly? Why do the initialize in data -> watch dance?

@balint42
Copy link
Author

balint42 commented Apr 7, 2017

I feel there can be a conflict of best practices for the 2nd scenario I describe - on one hand we are telling people

This means you should not attempt to mutate a prop inside a child component. If you do, Vue will warn you in the console.

On the other hand in the 2nd scenario you want the prop value to also depend on the child component not just the parent one. Following the rule not to mutate the prop that would mean having to introduce two vars, one as prop one as data for the same thing. And then whether you use the prop / data directly or as (computed) method how do you decide which var has precedence? What's the source of truth, you have a split brain scenario. watch to the rescue, let prop bind to data.

This at least is my humble undestanding.

@yyx990803
Copy link
Member

@balint42 the more idiomatic way to handle that is emitting an event to the parent and let the parent mutate the state.

@balint42
Copy link
Author

balint42 commented Apr 9, 2017

@yyx990803 we are quite deep into this specific watch pattern - perhaps we can leave that out of the PR, does explaining the edges of vue reactivity as below make sense?

  • primitive props in data are not reactive: data is not reactively re-running, it only runs once on creation
  • primitive props require v-bind to make those reactive at least in methods / computed / template
  • storing references to Objects in data (or methods / computed / template) does cause reactivity regarding these attributes with or without v-bind but is bad practice
  • storing only primitive attributes of Objects in data is equivalent to storing only primitives

(of course phrased cleaner with examples as in the PR)

@yyx990803
Copy link
Member

@balint42 your understanding is still a bit off. I'll try to clarify:

  1. It's more accurate to say that the data function is non-reactive and run only once. Props are still reactive when used in templates.

  2. Reactivity has nothing to do with whether something is used in v-bind or not. I'm not sure where you got that impression from - but it's most likely a misconception.

@chrisvfritz
Copy link
Contributor

This sounds like it may not be Vue-specific, but more a general source of confusion in JavaScript regarding how objects and arrays work. Since it does affect many users however, I think it could be good to do a blog post or cookbook recipe on it (I just added it to our todo list). This snippet from a curriculum I use for teaching JavaScript may help explain some of why you see the behavior you do in Vue - and in JavaScript.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants