Are container components necessary when using Redux?
Many people who is in the process of learning Redux gets stuck when container components are introduced. It looks like a bunch of boiler plate code and you might start thinking whether it really is necessary or not. And all the new files you have to create. We already have new files for actions, reducers, constants… and now also new files for container components!?
It can be frustrating, but there are some very good reasons for why it’s the recommended way of doing things.
First let me just give you a super short description of what container components are (A more in depth explanation can be found in the official docs).
You have your plain old React component that can look something like this:
import React from 'react'
const BlogPost = { header, content } => (
<div>
<h1>{header}</h1>
<p>{content}</p>
</div>
)
export default BlogPost
Then you have the container component:
import { connect } from "react-redux"
import BlogPost from "./BlogPost"
const mapStateToProps = (state) => {
return {
header: state.blog.header,
content: state.blog.content,
}
}
const ConnectedBlogPost = connect(mapStateToProps)(BlogPost)
export default ConnectedBlogPost
The purpose of the container component is to connect your React component to the store (that’s why the function is called connect :) . Easy to remember, isn’t it?). You pass in a function to connect that describes how to map the data from the store state to props in your component. connect also takes as argument the view component that the state should be mapped to. What comes out is a new React component that you can render! More info how connect works can be found in this gist.
So why do we do it this way?
The reason is to separate “how things look” from “how things work”. Many people thinks this sort of separation makes the code more easy to reason about. These are also some other advantages:
-
When using this strategy your code gets more decoupled. Your React view components is totally separated from the Redux specific code in the container components. If you sometime in the future decide to switch Redux to something else that has become even more trendy, then it’s a much easier job than if your components would be tightly coupled with the Redux code.
-
Another advantage to do it this way is that your code becomes more easy to test. You don’t have to mock the Redux store, but you can totally ignore Redux when testing your React code (It’s of course possible to test Redux too but that’s a topic for another blog post).
Sounds like good arguments, but I am just experimenting and learning, do I have to use container components?
It’s not a strict requirement to structure your code like this. You could subscribe to your store in your view components instead. It’s totally up to you. If it’s easier for you then I think you should go ahead and do it. But if you do, keep in the back of your head that it exists something called container components and that you could have use for them when your application grows.
And by the way all those files that the docs recommend you to create, you don’t have to do it. An acceptable pattern is to have your container components in the same file as your view components!