Reputation: 969
I am building my Redux (NgRx) App with smart/dump components, but I'm struggling with deciding how "dumb" the dumb components should be...
For example, I have a smart component (posts
) which has a dumb component (post-list
), which contains dumb components (post
). Until here everything looks nice.
To display some buttons I need to know if the user is admin
or not and I would need to pass the property admin
all the way down from posts
to post
.
Can I connect the dumb component post
to the store and get it directly from the dumb component. Or is the component in this case anymore dumb?
It would look something like this:
private admin$: Observable<boolean>;
constructor(private store: Store<AppState>){
this.admin$ = this.store.let(isAdmin());
}
I think this would save a lot of redundancy. Is this good or bad practice?
Upvotes: 19
Views: 5977
Reputation: 3315
The dumb components should be presentational components without any logic.
According to Dan Abramov Author of Redux, dumb components match the following criterias:
In angular
They should just display the information and handle events by input and output streams.
So my recommendation is to checkout the ngrx example app on smart and dumb: https://github.com/ngrx/example-app
Also you can see how I did the implementation of smart and dumb in the game. https://github.com/wizardnet972/tic-tac-toe
Note: Container components are also reusable. Whether or not a component is a presentation component or a container component is an implementation detail.
Presentational components receieve data through @Input() and communicate events through @Output() but generally maintain no internal state of their own. All decisions are delegated to 'container', or 'smart' components before data updates flow back down.
Hope that's helpful.
Upvotes: 9
Reputation: 1825
I would think 'dumb' as being reusable in a different context.
Dumb would only be of interest to it's parent.
A mantra I repeat to myself using angular 2. If it is getting complicated and confusing, rethink my strategy.
What about another level of components. admin mode is one child, non admin is another. Those child components could get their data via Input, and emit via Output.
Upvotes: 1
Reputation: 11
This question applies to any client-side framework including React/Flux as well as legacy Angular 1.x apps (usually via something like https://github.com/angular-redux/ng-redux) and as with many things, the answer is that it depends on your use cases.
You've asked two questions though. How dumb should dumb components be and how best to determine if a component should be dumb in the first place.
Question 1: For how best to determine if a component should be dumb in the first place:
In your specific case, I would ask the question: Will the Post List or Post components be used outside Posts? Is so, make the highest "level" the smart component (also called a container). For example, if Post will only ever be used inside Post List but Post List may be used outside Posts, then Post List should be the smart component allowing you to just "drop" it into other components more easily.
That exemplifies a general approach though. Ask if a dumb component will likely exist above or as a sibling to it's smart component, and if so, promote it and if not, leave it as a dumb component.
Question 2: How "dumb" should a dumb component be:
A dumb component needs to be passed anything that changes, and as a best practice, methods to call for any events that can occur based on user action.
For example: If text, images, or media are based on changes in app state, this data should be passed to the component. And if buttons, links, forms, or other clickable elements exist, passing at least optional callbacks/methods to invoke for these will provide the users of your component (even it's it's you) future flexibility as the app requirements grow.
Upvotes: 1