React why pass down functions to components anyway? - javascript

I am just wondering, why do we define every component function in one place (e.g index.js) and then pass those functions down the components? Does that make any sense?
E.g I want to define a click handler for a list button component, and another click handler for some forms button component, why would I define them all in one place? Isn't the divide-and-conquer approach better?
I mean, why would I not just define my click handlers in the components themselves, where they belong? beside the fact, that everything in one place gets messy and hard to upkeep...

I want to define a click handler for a list button component, and another click handler for some forms button component, why would I define them all in one place?
Because of the nature of the unidirectional data flow that React employs, state flows down the tree and events (i.e. changes) are passed back up via handlers such as the ones you mention. Components deep down in the tree can (or rather, should) only propagate changes back up via clickHandlers and the like.
The reason that handlers are often defined together in only a few places is because those places typically represent points where common state is shared, so the events that update that state need to be handled there.

Related

how to emit the data from child to parent without calling an event(vue 2)

I need to send the data from the child component to its parent(by emitting), once the child is loaded without calling any event like click or keyUp,...
in other words, I want once the child component is mounted, it automatically sends some of its data to the parent and not necessarily calling an event to emit the data.
is there any way to do that in vue.js?
I'll thank you in advance
Instead of using the $emit i suggest using some store (state management).
It could be global store or sub store. A thing that will make it easier to watch changes in any parent/child components.
Imagine that you want to listen inside a very deep child component from a parent one. Would you start passing around events ?
The flow is :
1- Update the store from deep nested child
2- use a store getter in your parent component to watch/compute changes
Checkout vuex https://vuex.vuejs.org/
I suggest you read about how props work: https://v2.vuejs.org/v2/guide/components-props.html
One thing you could try to do is pass an Object as a prop, and mutate that object inside the child, than monitor object changes in the parent. But to be honest that conflicts with the ideas of how Vue works, and is based practice. So don't do it.
But what is the problem really? Emitting a custom event is by far the easiest thing to do, and fully in line with Vue.
In parent:
<my-comp #initiated="handleInitiated"/>
In child, after you did the initial work:
this.$emit('initiated', initiationData)
If you are worried about event propagation when using default event names, this solution with a custom event name solves that. Of course you can also always stop further propagation once you caught it.

Ngrx update reducer if component is on the page

I have two components on a page, an update user form and a history of events. They are represented by two reducers (user and events). I want to update the list of events in the store (by calling an API) once once the user has been updated. However, the events should only be updated if the events component is on the page.
What's the best way to achieve this? The only solution I like the idea of is to have a success handler in a parent of the form / event components which dispatches an action which is caught by an effect which will then refresh the list of events. I was hoping this is something I could achieve entirely with effects but I obviously don't know if the component Is on the page and I also need access to route params. Does anyone have any better solutions or can see an issue with this solution?
Typically, the fact that the Events component is shown on the screen represents some sort of part of the "business logic/process" which is likely already represented in the store state. If it is not the case, you seem to need to add it in some way and update it when your events component initializes (ngOnInit) and is destroyed (ngOnDestroy).
Once it is part of the store, you can use it as part of the effect.

Is it harmful to nest too many components inside a single one?

I have a multi-selectable table component which contains a table-disaply component. Inside the table-display component there is another component called table-row.
table-selectable
| (contains)
v
table-display
| (contains)
v
table-row
I am doing this because I would like to make each component genereic enough so that it can be used for other purpose, Howere, I realise it is not easy to pass the action up the the parent component. The reason is that I have to carefuly wire all the actions inside sendAction method and the action name inside the hbs file and I feel this probbaly may cause error(s) in the long wrong.
My question is that is it harmful to nest tom nay components inside a single component like the one I did?
Javascript prepares an HTML DOM Tree of Objects in a document loaded. This DOM is then available to you to work around with its elements.
Javascript access to HTML DOM is still slower than executing javascript without accessing HTML DOM.
The level you have mentioned is not too deep nested, so far you are you are easy to access the inner elements.
Events generated by elements always propagate toward Execution Context which Javascript engine has created to run the piece of your code. So, you can work with these events on Global level (which is "window" level most of the time) until you are registering the listener with proper HTML element to listen to the proper event, otherwise this will not work. For example, a button fires a "click" event, e.g.
document.getElementById('mybutton').addEventListener('click', function() {
console.log('my button clicked');
});
So far as you are successful to select this button, and bind the "click" event listener, you are OK. But if your element selector is wrong, or you are trying to listen to the wrong event, this will not work.
So far as the volume of the page is concerned, the more the content, the more page load time. Also consider it as an SEO perspective.

Communication between components in Maquette

My question is about the communication between components in the Maquette Javascript framework.
Imagine I have a Menu sub-component used in an Application component: the Application instance would like to know when a menu item is selected in the Menu instance in order to swap the main content displayed in the application (for example). In other words, I need a way to communicate between a child component and its parent component. How can this be achieved in Maquette?
Sure, I can pass a callback owned by the application instance to the menu instance, which will be called when an item is selected. But I'm a bit reluctant to do that because the "selection" event is just a "rendering-side" aspect of the menu component, so I would prefer the event not to leak into my Menu API, but to stay inside the render function/method instead.
So, I would like to deal with events at the "rendering-side". But I guess it means I have to send a CustomEvent from the Menu's render function and register a CustomEvent handler inside the Application's render function, right? Is this use-case supported in maquette? Are there other alternatives to CustomEvent for my use-case?
Thanks!
PS: question reposted here from ticket #71 in order to get more answers.
What we usually do is pass callbacks to components that get invoked when items get clicked. A Menu could be constructed with a callback menuItemClicked(menuItem: MenuItem) for example. Imho this does not leak any application-specific knowledge into the menu/menuitem. The creator of the menu could do anything inside the callback like routing or changing a variable.
An event system is also certainly possible. I do not recommend using the DOM hierarchy to bubble the events though. I can imagine the Application creating the menu using menu = createMenu(...) and afterwards calling menu.addEventListener('itemClicked', navigate) or something.

Different actions for common components in FluxJS

In my flux application, I have a DropDown React component that renders itself with an array of Key Value Pairs.
I'd like to have two different drop downs, one with Country Data, and another with City Data.
In the Flux pattern, each dropdown would have a Selection Action that contains a payload of the selected value, which a corresponding store would use to update it's state.
How do I specify which dropdown Selection action belongs to which store?
I can create a wrapper component that is specific to each need i.e. CountryDropDown and CityDropDown, and have each create their own specific action CountrySelected and CitySelected but is that the idiomatic approach? If it is, how do I wire up the underlying DropDown component so that it's onChange handler fires the parent's action?
Actions should not belong exclusively to one store or another. This is very much like creating a setter method in the store, which is antithetical to Flux.
One of the central ideas behind Flux is that all stores are informed by all actions. The dispatcher is the mechanism by which actions are distributed to all the stores. This keeps the flow of data open to changing needs.
There are probably a few different solutions to your problem.
I would consider adding a selectedType field to the action that is either 'city' or 'country' (or you could use constants instead of strings). You could pass this value into the React component as a prop, if you are trying to keep it abstracted.
Likewise, if you would rather have completely flexible control over the behavior of the child, and you want to define that in the parent (your final question above), you can pass a callback to the child component as a prop.
You could have separate actions dedicated to each type, as you described, but that seems like duplicating code to me.

Categories

Resources