I have just started to use Flux in my project, but I find it difficult to reuse a component (or have multi instances in different places) when it's complex. By "complex" I mean a component includes some smaller components and may involves some interactions of changing some data. For example, a component containing a list, a adding new input and button.
I can come out with two ways of solving it:
Passing all functions that handling change events by props from
parent, so the component will not know which action is really
called. In this way, there will be a lot functions passing down for
different levels' components.
Passing an 'identifier' object when calling
action. In store it will access corresponding data located by the
'identifier'. This way there is added logic and parameter
"identifier".
I haven't found a best way of handling this, basicly because store and action in Flux are singleton. Is there any more elegant way to solve this? Thanks!
Related
I am building an application with a lot of screens (components) each one has some methods such as save, add, delete, redo, view, and other functions. every function of them has a lot of code in it.
now I have declared these functions outside my components and call them from my methods attached to the screen component so I can access them. when I call them I pass this keyword as an argument so I can access the state and props from these functions.
I did this to be able to share this logic across the components.
now my question: Is this a best practice?
if yes what is the best way to do this
if not what should I do instead
note I am using react
You can use a Custom Hook that contains all the re-used logic you have if that what's you want.
Read more about this feature here:
https://reactjs.org/docs/hooks-custom.html
https://www.w3schools.com/react/react_customhooks.asp
I have a little question about Angular Components.
I often read that you should use components only to display data and interact with the user, and for your "business logic" you should prefer services.
So my question is the following (just an example):
Let's say I have made a component to upload files via drag and drop. I have the logic to get the data from the drag and drop and store it in an array (and maybe much more other functions) inside that components typescript file.
Now when I am including this component twice inside one parent component (because I need two upload fields for example), are both referencing to the same or is also the program logic inside that component created twice for each instance?
If so, then I should try to keep as much shared program logic as possible in singleton services so they are only created once at runtime and not wasting memory etc., shouldn't I?
Hope somebody understands what I am meaning :).
thanks in advance!
If you add the component twice into your parent, then two different instances will be created (each owning unique scope).
You should however abstract upload/handling logic into a service. Provide that service in module to make it a singleton. If you want instance per component, then provide it inside component.
If you create two components in your template which are similar for example:
<app cumstom></app custom>
<app cumstom></app custom>
This will result in two objects being created who both have their own model (data) and view. They don't know anything of each other.
If you want them to communicate it is often smart to use a service which you can inject into both components so they can share the same data. If a service is provided in your ngmodule is will only be created once (so it is a singleton).
Well I think what you need is a smart component, where you can put your boths uploads-component and inject your service logic in this smart component. The smart component will be responsible to provide the bridge of the common logic between the two components.
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 :)
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.
Maybe at official flux website I saw a video were mentor said something like:
Only top-level React views should know about stores. All not top level
views should be dump and receive all information as properties.
Question: Is that right? Your argumentation, please
BUT, suppose you have some small React view Button.react that's reused on multiple pages. And suppose Button.react must know about some store data. If we won't fetch all data directly from the Button.react, we get a duplication of code at each top-level component which reuse Button.react. Is that ok for you?
I hope I am understanding your question.
One of the characteristics of React is its one-way data flow. Each component can be used by another component, just like one function can call another function. Just like a function, a React component should typically be able to get all the info it needs to do work (render itself) from the arguments passed into it. This is the function of props in React. When using Flux, sometimes the React Components, which are typically near the top of the view hierarchy, that actually fetch the data from the stores to pass down thru the application are called Controller-Views.
It is not an enforceable rule that every component doesn't become a Controller-View, getting its own state directly from a store, but it is a general practice for good reason. consider the two functions:
function renderToggleButton( isSelected ){
//... render the button
}
vs
function renderToggleButton(){
var isSelected = StateStore.getButtonSelectedState( id );
//... render the button
}
I think you will agree that the second function is more complicated and difficult to test. It has to know from where it is getting it's initial conditions. It also has to know how to identify itself in the context of the application. These are two things the function should not have to know.
Now imagine an application full of functions like this. If one function is misbehaving, it becomes very difficult to trace its inputs; to test it under controlled conditions. I hope that clarifies the guidance given for passing data thru the application as props.