Do you always need a separate <Container/> and connect() for each component when using React and Redux?

I just finished doing the Markdown Previewer requirements and just need to style it and probably do the bonus challenge. I created two components, <EditorComponent/> and <PreviewerComponent/> and needed to create two separate container components using two separate connect functions in order to get the main tests to pass.

I tried to render the two components inside a <MarkdownPreviewerComponent/> and tried to connect this main component to the Redux store. This did not give <EditorComponent/> and <PreviewerComponent/> access to the Redux store. So is the only way to give multiple components access to the Redux store by creating a container component with a separate connect function for each and every one? Thanks for any help.

If you want it directly connected to the store, yes. If you don’t wrap your component in a connect component it’s not going to be able to connect to the store you’ve got defined: it’s not magically getting values out of thin air, you need some way for a component to read the state of the store, update it, and subscribe to changes. By defining it, it’s exactly as if you have this for each component, just with less typing needed:

  // logic in connect subscribes to the store and
  // passes the values you want from the store's
  // state via props to...
  <MyComponent />

It works the same as any other components, you pass down the props you want down. And the connect function wires that up for you, takes away the need to write the boilerplate code you’d need otherwise. You can still pass the props down as normal – like the top-level could talk to redux, then the sub components just accept props you pass.down that way. But you still have to actually pass them, it’s not implicit

Note in newer versions of react-redux you wouldn’t use the connect functions, you would use hooks; its generally easier to read and to write and grok than the connect and mapState/mapDspatch functions

1 Like

Thanks a lot! I forgot to pass props to the child components when they were being rendered inside the main component.

Btw, I passed props using {…this.props} for one of the components, since it uses all of them, and then I explicitly passed only one for the other component. Could I just use {…this.props} for everything, or will there be major performance hits with this approach?

There may be performance hits: a component rerenders every time it gets new props (it’s a function, and will be executed every time the arguments are changed), and by doing that have no way to specify exactly what props are going in. The perf difference is not likely to be hefty, probably not noticeable. However, it’s not good practice at all to do that because it obfuscates your code. You should be explicit about what parameters those functions need to be called with, cf

const Person = ({ name, age }) => (
  <p>{ name} is age {age }</p>



Is much clearer than this (which is saving a bit a typing in exchange for not actually specifying what the Person function actually takes as parameters):

<Person {...this.props}/>

It is useful in a few cases, but generally it’s not great practice

1 Like

Thanks again!

I finished the bonus and started to style the project. I want to have the <EditorComponent/> on the left side and the <PreviewerComponent/> on the right side. I couldn’t do this with just one <AppWrapper/> and a single corresponding <div/> in the <HTML/> portion. I had to do an <EditorAppWrapper/> with a corresponding <div id="editor-react-component-container"/> and a <PreviewerAppWrapper/> with a corresponding <div id="previewer-react-component-container"/>. I also created an <EditorProvider/>, a <PreviewerProvider/>, and two ReactDOM.render() methods. Is this the proper way to arrange multiple components in a page?

Here is the Markdown Previewer that has the <EditorComponent/> on the left and the <PreviewerComponent/> on the right.

Here is the Markdown Previewer that does not arrange the components properly. I tried to use a Flexbox and then I tried to use a Grid, but nothing happened.

Thanks again for all your advice.