Should derived data be the responsibility of the NGRX store? - javascript

Should derived data be the responsibility of the NGRX store through selectors or should it be defined on the component that will use it? For example, let's say you have an object with startTime, itemsCompleted, and itemsRemaining. A utility function calculates some other properties such as expectedLate, expectedOverage, etc. Should that take place inside a selector or locally on the component? Does it matter?

Personally, I like to use selectors for derived data. A component just retrieves data from the store and displays it.
This imho makes selectors and components easier to test.
Following this convention it's also easier for devs to find the information they are looking for.
Also, you have one single source of truth. For example, if a user logs out you just have to update the user instead of updating the user and setting a isLoggedIn flag to false.

Related

How best to use Reactive State?

I have a big component, I store all the information about the selected items and all the information in the store(ngrx).
There are different types in this component and I can switch between them and change information about them(via inputs). And then, at the click of a save button, send all changes to the server.
What is the best way to put changed data in the store?
Send to the store during an onchange event (minus: a lot of dispatch)
Send when switching between types (minus: you need to somehow check the status of the type that has been changed right now before pressing the save button)
Or, in general, is it a bad practice to put elements that will change, and better store them to service?
And another question, is it correct to carry out calculations in a reducer. For example, I dispatch a list of elements in the store and I need to add a new element for the selected type. I can do this through the service, but then I need to pull out all the elements, the selected type and a few more parameters, and then perform actions and put the changed array back into the store. Or do all these actions in a reducer with known data.
Or in general, is this the wrong architectural approach to keep this list in the store?
Without knowing the use case it's hard to give a correct answer to this question, because it all depends on the needs.
As a rule of thumb, if the state only affects the current component, the ngrx store is not the place to store its data. An example of this is a form, it's usually an overkill to sync the form with the state in the store. That being said, if you need rehydration on the form, it's a good use case to keep the form and the store in sync.
The minus of dispatching a lot of actions, isn't a "real" downside of it imho - the ngrx store (redux in general) is designed to handle a lot of incoming actions.
To answer the second question, yes that's were reducers are for imho - it's here where I expect some logic. See the redux docs for more info.
You can also put some "view logic" inside the selectors, like filtering, sorting, paginination, ...
Mike and Brandon gave a talk at ng-conf and they explain what should belong in state and what does not. The talk gives useful insights, Reducing the Boilerplate with NgRx

React props: Should I pass the object or its properties? Does it make much difference?

When passing props should I pass the entire object into the child components or should I individually create props first in the parent component and then pass those props to the child?
Pass entire object:
<InnerComponent object={object} />
Individually create props that're needed first:
<InnerComponent name={object.name} image={object.image} />
Which one is preferred and if it depends, what should I use as a gauge to use either?
According to the principle of least privilege, this is a correct way:
<InnerComponent name={object.name} image={object.image} />
This restricts InnerComponent from accidentally modifying original object or accessing properties that aren't intended for it.
Alternatively, properties could be picked from original object and passed as props:
<InnerComponent {...pick(object, 'name', 'image')} />
If there are numerous properties that are tedious to list, there may be single prop that accepts an object:
<InnerComponent object={pick(object, 'name', 'image')} />
You should prefer your second example, to pass the props individually.
There you can see explicitly which arguments are passed and can quickly compare with which arguments are expected. This makes collaboration along people much easier and makes the state of the application more clear.
I personally try to avoid passing whole objects if it's not needed.
It's like the spread operator where there can be any property inside and it is much harder to debug in a bigger scope.
Some additions to pure react like prop-types or typescript might help to define clear and expected properties in a big application
Since JavaScript has no type annotation, the second choice would be much preferable, as mentioned by #mstruebing the code will be more maintainable. However, if you are using TypeScript React (which support type annotation), both choice would be equally clear. But do keep in mind, the first choice promotes tight coupling between views and models, this allows fast development as you don't have to type much; while the second choice might slows down development but you have higher flexibility and tolerance to future changes.
So, the gauge is: if you favor development speed over flexibility, go for choice 1; if you favor flexibility over development speed, go for choice 2.
Extra notes
Ok, when should we favor development speed over flexibility? Here's my 2 cents.
If your project was meant for short-term usage (for example developing an app just for collecting votes during election), then go for the first choice.
If your project was meant for long-term usage (for example online bank transaction portal), you should go for the second choice.
Passing multiple props to a child component is the preferred way of passing props to child components. This will help you in tracking the state of the application in the child component.
Also, feel free to use the prop-types module. It acts like generics in Java and provides type safety for the props to pass in.
If you aren't making use of all the properties within the object, its better to pass the required properties separately as it can help in performance optimisation when the Child component is a PureComponent of use shouldComponentUpdate. In such a case, only when the props used by the Child component change, its will re-render and not when an unused property from within the object has changed.
However if your are making use of all the properties within the object, it doesn't make much of a difference event if you pass down the object as a props, provided you handle the mutations of the object correctly.
I agree with the other answers that in short, it depends, and the points raised in other answers are all valid.
Some other points I would like to add that also leans towards using individual properties are as follows -
Sometimes its not even the question of whether Do I need all the properties? It should be more of the question - Do I want to restrict the usage of the component to when I only have the complete object and not just a subset of properties.
Take for example a widget to display a car's image, make and model as part of a list of a widgets, its not reasonable to expect the full Car type to be available in order to display only the car's image, make and model. Only those 3 properties are required.
With the likes of rise of the likes of graphql where we can restrict the properties of data being returned about a type, we shouldn't always assume that components will have access to fully populated objects based on a type.
Lastly on the point of causing unnecessary rerenders of components down the tree, always passing the full object around, you are likely to cause all children that consumes that object will rerender when the object is updated. However passing separate properties to children, usually primitives, we can better mitigate against unnecessary rerenders
The whole point of objects is to encapsulate similar properties together. If you have about 10 properties and want to use them in your child component, stick with objects.
But in your case, my opinion is to use your second example as it makes the code in the child component simpler.
To the best of both worlds simply destructure those props that you need inside your child component.
Like this:
function InnerComponent({ name, image }) {
...
}
If you don't like braces in the arguments do this:
function InnerComponent(props) {
const { name, image } = props;
...
}
It depends on that Object. Do you need ALL of its properties to be passed to another component? Or... You might need to pass 2 properties out of 5 to a specific component?
If you don't need to pass ALL of its properties, I recommend passing
the Properties as Props
BUT, if you are 100% sure that you NEED ALL THE PROPERTIES to be
passed together, I recommend passing the whole Object as Props in
that case as it would be much clearer code and keeps you away from
forgotten to pass something. For example; When you add a new property
to that object, you don't have to pass it, as you are already passing
the whole Object!
Well, if you aren't certain about your current/future purpose of that Object as you might need to EXCLUDE some properties soon, you probably should pass its properties individually in that case, instead of passing some non-used properties to the other component.
You can pass props into JSX element as single object using React.createElement function.
Because each JSX element is just syntactic sugar for calling React.createElement.
The following 2 lines are equal for React:
<Button variant={"secondary"}>Add</Button>
{React.createElement(Button, {variant: "secondary", children: "Add"})}

Reusing parameters among Angular components

When I'm sharing data among components should I call that data only once and provide it as #Input() or should I call that data again on every component's cycle?
For example, I have the following components in one page:
<game-info [id]="params?.id"></game-info>
<game-leaderboard [uid]="auth" [id]="params?.id"></game-leaderboard>
<game-progress [uid]="auth" [id]="params?.id"></game-progress>
Where I get the id from the ActivatedRoute and the uid from my authentication service. In some cases, I'm also passing a data input for multiple components in the same page.
One problem I face is that, sometimes, I'm passing data to many children components and it was harder to debug. For example:
game.component.html
<game-details [data]="data"></game-details>
<game-progress [data]="data"></game-progress>
Then, on details.component.html, I'd pass data as an input to another component - and so on. It became a really long chain:
<game-info [data]="data"></game-info>
<game-players [id]="(data | async)?.$key></game-players>
Is it a proper approach? Or would it be better to get those parameters inside of every component?
Another issue, for example, sometimes I need to get the an async parameter (e.g. uid from an Observable) during onInit but it didn't receive it yet. So, I was wondering if I should just call those parameters straight in the component instead of passing them as an input.
PS. I'm not sure if this is off-topic. If so, please feel free to remove it.
Nothing wrong with that approach. Actually, this is 1 of the recommended ways nowadays where your top-level 'smart' components would gather the data and then inject that data to your 'presentational' aka 'view' aka 'dumb' components. Note that data also flows the other way around: all Events are emitted upwards, where they are handled by the containing 'smart' component. See here for a good (better) explanation.
I must say this approach has been working very well for me: code is clean (clear responsibilities, reusability and testability of presentational components...) although I must admit I share your concern that it might become a bit tedious when you have quite a lot of nested components.
A common approach would be using it as a Injectable service.
For its benefits, as it says:
The component can create the dependency, typically using the new
operator. The component can look up the dependency, by referring to a
global variable. The component can have the dependency passed to it
where it is needed.
For angular 1, check https://docs.angularjs.org/guide/di
For angular 2, check the first answer in What's the best way to inject one service into another in angular 2 (Beta)?
It is hard to answer the question since I am not sure exactly what you are trying to achieve but it might be worth looking into services. Services will have one shared space for the components under the component it is declared under(example the app.component or even app.mudule). Then you can pass the new parameters to other components through the service. That would be the proper way of having a shared state and you can pass through many components by just injecting the service.

Should I use a single Model object for the whole SPA or many small models for each component?

I am thinking about how to organize Model in my webapp. I have two options, as I see it:
Create a single globally available Model object, then on instantiating new components they must register themselves in the Model object via methods, then update it when their state changes. Others would listen to changes from the Model by some key.
Create a model object for each component and let others know via some Event dispatcher about their state change.
In 1st case I feel like it will be easier to manage all the state change in one place, have more standardized way of doing it, while with the latter scenario I think it will be harder to maintain consistence over the system.
What are the factors I should base the decision on?
I would go with the first but adding the idea of the second: Instead of the components checking constantly the keys for changes you can make the only model signal the components when needed after they register. You can pass the signal/callback with the register itself.
That way you don't need to create an army of models that update themselves (that might also mean you have to avoid cyclic propagation). In addition to this, if I understand correctly it would violate the single source of truth. Also it looks worse both memory and performance wise.

Where would you instantiate nested components using Closure Library?

Closure library offers a basic life cycle for Components:
Instantiation
Rendering/Decoration
Document Entering
Document Exiting
Disposal
I'm focusing on the first two. About design patterns, when is it better to instantiate a nested component in the first steps?
Instantiation: needs to be hold on a property till added through addChild and consumes memory before necessary. Anyways, it allows to do some dependency injection or better initialization because of the parameters it receives.
Rendering/Decorating: messes up the dom creation, which can be already complicated because of the references of other objects it needs. It also would need the instantiation parameters previously stored in some property. Anyways, holds the instantiation till is needed.
Maybe a separated method called after instantiation which wraps the rendering? I'm asking because Closure Libray book and documentation don't talk about this.
Doing some refactorying and trying to split logic, came to the following conclusion:
The best option I've found so far is to create the components inside the createDom method:
Normally, the parameters needed for components involve the data they present. My arquitecture uses DAO, which means all data objects are conveniently connected. Subcomponents usually need some other data objects which are accessible by the parent's DAO. Since the parent object is needing this DAO, it's ok to store it on a property for the use inside the createDom.
The other thing is that instantiation and rendering in the createDom component, theoretically, only needs two lines, which isn't a mess.
Again, it's the best possible solution to increase cohesion.

Categories