Skip to content

Quickstart: Container Component

JamieB edited this page Jun 20, 2018 · 1 revision

Shared components can be connected to the Redux state using "containers". For more details on how presentational and container components work, see this description.

Containers can be created for any shared component, regardless of whether it comes with bundled actions and reducers. When the component exists on its own, any state management functionality (actions and reducers) is created at the page level. However, some components include corresponding scoped actions and reducers, which can be plugged into the state of a page wherever this component is used. In this way, the component remains reusable, but the boilerplate of managing its corresponding state is reduced.

Example

Here we're going to add the component MyComponent to the page MyPage. To do that, we create a container, which is responsible for mapping the page's state to the presentational component MyComponent. This component happens to come with scoped actions and reducers, so we will use those too.

MyComponentContainer.jsx

Sits here: pages/my-page/components/myComponentContainer.jsx.

// ----- Imports ----- //

import { connect } from 'react-redux';

import MyComponent from 'containerisableComponents/myComponent/myComponent';
import { myComponentActionsFor } from 'containerisableComponents/myComponent/myComponentActions';

import type { State } from '../myPageReducer';


// ----- State Maps ----- //

function mapStateToProps(state: State) {

  return {
    propertyOne: state.page.mySection.propertyOne,
    propertyTwo: state.page.mySection.propertyTwo,
  };

}


// ----- Exports ----- //

export default connect(mapStateToProps, myComponentActionsFor('MY_SECTION'))(MyComponent);

We start by importing the shared component MyComponent, and its corresponding actions. Then we create a function to map the page state to the component's props, with mapStateToProps. Note that we can import the State type from the page's reducer here, to make sure that flow checks our Redux state lookups.

The final line puts it all together, using the connect function provided by React-Redux. It takes our state mapping, and an object containing the scoped action creators for our components. For more information on how this works see the section on Scoped Actions and Reducers in the docs.

Finally, let's look at the page reducer, to see how the component's scoped reducer fits into this:

MyPageReducer.js

// ----- Imports ----- //

import { combineReducers } from 'redux';

import {
  myComponentReducerFor,
  type State as MyComponentState,
} from 'containerisableComponents/myComponent/myComponentReducer';

import type { CommonState } from 'helpers/page/page';


// ----- Types ----- //

type PageState = {
  mySection: MyComponentState,
};

export type State = {
  common: CommonState,
  page: PageState,
};


// ----- Reducer ----- //

export default combineReducers({
  mySection: myComponentReducerFor('MY_SECTION'),
});

Here we import the scoped reducer for MyComponent, and make it part of the page's reducer using Redux's combineReducers, described here in their docs. We also retrieve the State from the component, to make sure that flow is able to check all the types.

πŸ™‹β€β™€οΈ General Information

🎨 Client-side 101

βš›οΈ React+Redux

πŸ’° Payment methods

πŸŽ› Deployment & Testing

πŸ“Š AB Testing

🚧 Helper Components

πŸ“š Other Reference

1️⃣ Quickstarts

πŸ›€οΈ Tracking

Clone this wiki locally