loading...

Is it true that components in a ReactJS app should be divided into container components and presentational components?

sunflower profile image sunflowerseed ・1 min read

I guess it is "you don't have to do that", but is it actually good or best practice to actually do that? And if that's the case, how should that be done?

Discussion

pic
Editor guide
 

As you said, it is completely optional.

There are two reasons why you may want to separate into containers and presentational components:

  1. You can reuse either independently of the other.
  2. Apply the single responsibility principle (code is much easier and safer to work with).

Answer: Separate them if you want the benefits or if you just feel like it. Otherwise there is no reason to. Personally, I lean towards separating them.

In more detail:

Reuse components

If a view is dumb, it can be reused anywhere else in the codebase. You can even put it in an NPM package and use it in other codebases.

One example for this may be a different view for blog posts. Maybe you use the same container, but depending on user preferences or something you can have two different views for the blog posts.

Same with "container logic" (things like getting data and such). Using custom react hooks, you can put logic in there and import them in multiple different containers. This allows you to reuse logic.

For example you may have a single view for blog posts, but perhaps have two different ways you can obtain data for blog posts. Two different containers, which both use the same view.

Single responsibility principle

If logic and views are bundled together, then when modifying either one you could break the other. Also you are working with more code, so there is more to read and understand before you can change anything.

Separating them improves this.

 

One of the original articles that really popularized this idea, by Dan Abramov of react, has since been updated to specifically say that this pattern may actually not be as ideal as originally thought . See here “Presentational and Container Components” by Dan Abramov link.medium.com/CRpzy7wJF4

And this tweet: mobile.twitter.com/dan_abramov/sta...

It's really up to preference and situation.

 

To be true is approach is a little bit outdated when you are using hooks. Introducing hooks was breaking this rule as hooks are our "containers".

In old approach we separate concerns in this way:

// LoremContainer.js

class LoremContainer extends PureComponent {
 componentDidMount() {
  // perform redux actions
 }

 render () {
  return <LoremComponent {...this.props} />
 }
}

export default connect(reduxProps, reduxActions)(LoremContainer)

// LoremComponent.js
class LoremComponent extends PureComponent {
 render () {
  // component markup
 }
}

Now when we are using hooks we are using something like:

// LoremComponent.js
const LoremComponent = () => {
 const { props, actions } = useRedux(reduxProps, reduxActions)

 return (
  // component markup
 )
}

// useRedux.js
const useRedux = (props, actions) => {
 // perform redux bindings

return { props, actions }
}

Summary:
We replace container-component technique in favor of using hooks but we still use separating concerns

 

in the past (without hooks), isn't it true that we can also get by if we use connect and just directly connect to LoremComponent? In the past we didn't have to use a container... but I guess if it is like a component that has 3 other components, then it makes sense to have a container...

but even so... the container can just be a presentational container... and contain 3 stateful components...

or maybe it the past, it means, to always use stateful components (to be container components), and purely non-stateful component (to be presentational components)...