Daskus
Daskus

Reputation: 969

How "dumb" should dumb components be?

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

Answers (3)

Shlomi Levi
Shlomi Levi

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:

  • Are concerned with how things look.
  • May contain both presentational and container components** inside, and usually have some DOM markup and styles of their own.
  • Often allow containment via this.props.children.
  • Have no dependencies on the rest of the app, such as Flux actions or stores.
  • Don’t specify how the data is loaded or mutated.
  • Receive data and callbacks exclusively via props.
  • Rarely have their own state (when they do, it’s UI state rather than data).
  • Are written as functional components unless they need state, lifecycle hooks, or performance optimizations.
  • Examples: Page, Sidebar, Story, UserInfo, List.

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

Derek Kite
Derek Kite

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

Jason Chaney
Jason Chaney

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

Related Questions