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?
Focus on the UI: Almost all basic UI components should be considered dumb components. Examples include loaders, modals, buttons, inputs, etc. Accept props: Dumb components accept props to allow them to be dynamic and reusable.
What is a correct usage of smart/dumb component pattern? IMO the correct usage is generally to limit the scope of state and logic as much as possible, only exposing out state and mutators on the API when necessary (i.e. lifting state up). There is also the consideration of separations of concerns.
Dummy Components are the exact mechanical equivalent of fully functional, electronically active components. Dummy SMD components are available in all popular IC fine pitch packages including PoP, TMV, WLP, BGA, Flip Chip, CSP, QFP, LQFP, TSOP, TSSOP, SSOP, PLCC and also resistors and capacitors.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With