Vue.js - Children to children component communication - javascript

I'm currently working with Vue.js for a project of mine. I'm using the component system and I'm not in the position where I would really need the ability to have two children components (sharing the same parent) to communicate between each other.
In this particular case I basically only need to have one of the children read a variable in the other child.
I'm looking for a nice, clean way of achieving this. Any suggestions will be appreciated.
It would probably be possible to use this.$parent.$children... etc but I'm looking for a more clean way if possible.

I recommend declaring the property in the parent and via props bind it two-way from the parent to the component that manages the value and bind it one-way from the parent to the component that needs to only read it.
Based on your provided fiddle here's an example of that:
http://jsfiddle.net/yMv7y/662/
Instead of sending messages, you let binding take care of the information transfer.

Related

Is it possible to change value of props via vanilla JS?

In the past, our small team have been using Adobe's Target to perform A/B testing.
Before Vue.js, our applications was relatively simple -- just plain vanilla JS. It was fairly straightforward to do any DOM manipulation (or any data manipulation) since not many things on our application's data was decoupled to anything.
As we are transitioning to Vue.js, the concept of modularizing into components and passing information via props would mean that we may not be able to change props directly from Target's perspective.
However, I noticed that Vue Devtools extension allows you to change the props directly.
Is it possible to do the same thing by vanilla JS?
I think it's not natural to change properties from target component. In Vue.js the model is "Data down - Actions up". This means that you pass some data from parent component to child component and if the child component have to change something, it should emit an event and its parent component should listen for it and react to it. If you need flexibility and your data changes dynamically, you can pass objects via the props and also emit event with objects as payload. I think this is how you should approach the new implementation of your application from vanilla JS.

ReactJS component communication

I am wondering what is the recommended way to communicate between ReactJS components. I took a look at a related question. However, I did not find the answer sufficient. The key approaches seem to be the following:
Assume that only childs / parents communicate.
Communication from parent to child is realized by setting props, the reverse is realized by passing a callback as a prop.
This has the following disadvantages:
Since siblings can't communicate directly, all state which has to be passed back and forth between siblings has to be stored in their common parent. This means that the parent has a lot of state which it doesn't really need.
Passing callback is rather inelegant.
What I would like to do is to add to components methods / members in order to establish communication. I am thinking along the lines of RxJS. This would mean the following:
I accept that communication is out of the scope of functionality handled by ReactJS. This seems to be the case anyhow.
The members of classes need to be persistent. For example, a parent component should not create a new <Child /> during each call to its render function since in this case all the subscriptions would have to be reestablished. Instead the constructor would have to create a this.child = <Child /> object and in the render call render {this.child} instead.
My question is: Is component communication somehow handled by ReactJS or is this something that should be taken care of by the developer in some other way?
In the first case: Is there a scalable and elegant way that communication between components can be realized in ReactJS? Is the rationale of the developers of ReactJS is done in the way described above or is there something I am missing?
In the second case: How should the components communicate instead?
Well there are two established way in React to communicate between components.
Observable architechture: Mobx
Flux like architechture: Redux
Note: Look at mobx if you are not sure what to start with :)

Why is two way binding between a parent component and a child component bad?

I've been doing development mostly in AngularJS, recently I was looking into Vue.js and reading its guide, on one page it mentions:
By default, all props form a one-way-down binding between the child property and the parent one: when the parent property updates, it will flow down to the child, but not the other way around. This default is meant to prevent child components from accidentally mutating the parent’s state, which can make your app’s data flow harder to reason about.
This is from https://vuejs.org/guide/components.html#Prop-Binding-Types.
I'm wondering if there are any principles of when to use two way binding, and when not to?
For the case where the child component needs to manage an array variable, it seems that two way binding would make sense.
For example, say I want to make my own Vue.js or AngularJS version of http://selectize.github.io/selectize.js/.
If two way binding is used, I would just pass the parent component's array to my Vue.js or AngularJS selectize component, and let the selectize component manage it.
If two way binding is not used, it seems the alternatives would be:
a. Either the parent component would either have to manually update the array when an item is added/deleted
b. Or the parent would have a function that manually sets the array, this function is then passed to the child component
c. The child component dispatches an event which the parent component listens to, and updates its array
I think these are the alternatives? Both seem more verbose and does not appear to provide much benefit.
This is one example, but I think many components would have this issue, another example would be if I have a product-selector component, it would be convenient to just pass in an array variable into this component, and let the component manage the array to reflect the selected products.
My main questions on this are:
Is my idea of the alternatives to two way binding correct?
For the mentioned cases, is there an advantage to using one-way-down binding? (I do not see the alternatives providing much advantage to avoid "accidentally mutating the parent’s state")
If (1) and (2) are correct, what is an example where one-way-down binding, provides a clear advantage to avoid "accidentally mutating the parent’s state"?
"one-way-down binding" is just a principle, similar to OO's Encapsulation, to reduce code complexity.
In my opinion the author didn't mean not to use "two way binding" (actually vuejs support that), just mention you don't abuse it.
In your examples, the product-selector is similar to native input, surely I think you can use two way binding, just like v-model does.

What is the good way for child to parent communication using inverse data flow in ReactJS?

I was wondering something about the reverse data flow in a React app.
Considering this question: data flow in react application and this article http://facebook.github.io/react/docs/thinking-in-react.html
We can see that the "normal" way to communicate from child to parent component is using callback passing through this.props.myCallback. (the StackOverflow article is a good example)
My questions are:
I understand the concept but what if we have deeper components? We would have to pass this callback to every component between the top parent component who hold the state and the actual triggering component. And if there is 3 to 4 components between them, I would have to pass the callback using this.props in each component.
Why not using an Event Emitter? I could send an event from the deep child component and then listen to this event in my top state parent component. This way we could avoid all the code between these two.
Please tell me what are your thoughts about this!
I learnt the hard way that it is a good practice to keep as much logic as possible in the highest level in the hierarchy of your components. Dan Abramov well expressed this idea in the article Smart and Dumb Components, where Smart Components are those that hold the logic, whereas Dumb Components are just meant to display.
So yes, the callback mechanism works well when you simply want to update the father's state, or you want the father to do an action whose logic you do not want to belong to the child.
When you have anything slightly more complicated than this I would suggest you go with a Flux-ish architecture of your taste. Flux indeed uses node's EventEmitter to communicate with the components.

ReactJS - How can a child find its parent?

Is there a way in ReactJS for a component to find out who it's parent is?
EDIT 1: Regardless of the merits of doing this, is there a way?
I haven't found a React way to do this - from what I can see, the idea is to pass callbacks down to the child from the parent, and the child calls the callback - unaware of the fact that the callback is actually on the parent.
I've tried setting an "owner" property, and that idea seems to work, but I wonder what's the best approach?
e.g.
<Parent>
<Child owner={this}/>
</Parent>
Then in the child component, I can do owner.method, and it seems to work fine. I know this isn't a true parent/child relationship, but is the closest I've found in my tests.
Some may say that callbacks are a cleaner way of doing this, but the parent/child relationship for some things (e.g. RadioButtonGroup and RadioButton) seems natural and would benefit from knowing this relationship, in my opinion.
EDIT 2: So it's not possible?
The thing that I don't like about the idea that it's not supported is
that HTML can be marked up with zero javascript - and it has implied,
default functionality - some elements are required to have parents -
they are defined as children of other elements (e.g. ul and li). This
can't happen in JSX because if there is interaction between the
elements - there has to be javascript events that bind the
components together - every single time you use them. Designers can't
simply write HTML like syntax - Someone has to step in and put some
javascript bindings in there - which then makes the maintenance
harder. I think the idea makes sense for overriding default behavior,
but default behaviors should be supported. And defaults would
require knowing either your parent, or who your owner is.
There are a number of benefits to not doing this, the main two are: reusability and encapsulation.
TL;DR you probably don't want to do this ever.
Let's say our RadioButton has this public interface:
<RadioButton active={true} onSelect={function(event){}}>text</RadioButton>
We could construct another component called SuperRadioButton, which might have a different way of presenting itself, but still have the same public api as RadioButton, so it's a valid child of RadioButtonGroup.
If we're accessing the parent, then the parent's internals become part of the public api of these components, and we need to be much more careful with how we change our code, because a change in any of these components could cause the entire application to break.
Callbacks. Owner properties. Passing events out to be caught by the root in the tree. Passing the root down through contexts.
There are ways, yes, but they're contrary to the conceptual model of react, which is to be explicitly top down at all times. The short version is "you can, but don't."
The fundamental problem is that you don't want a child mutating outside its parent's knowledge.
That means that the sole exception to this is the root of the component tree, so it's semi-legit to pass a member of that control downwards in props or contexts then to "pass things up" by telling the root, which may then repaint itself.
The application layer Flux does something not terribly dissimilar to this, but passes things outside of the component heirarchy entirely to a dataStore, which broadcasts things back in with events.

Categories

Resources