Containers

Next up we want to bind our Views to our Reducers, a.k.a. define how we get the props from our state.

Initialize

First up we need to add a new dependency, react-redux to connect our React views to our state

yarn add react-redux

and the type definitions for it

yarn add -D @types/react-redux

IndexContainer

We begin by creating a file called IndexContainer.ts inside our index-folder inside src/modules

All containers will have the same "prefix" as their accompanied views, a.k.a. [Pagename]Container.ts

import { connect } from 'react-redux';
import { State } from '../../redux/reducer';
import { setTitle, saveTodo, setDone } from './IndexReducer';
import IndexView, { IIndexState, IIndexDispatch, IIndexProps } from './IndexView';

const stateToProps = (state: State): IIndexState => ({
    title: state.index.title,
    todos: state.index.todos,
    loading: state.index.loading,
});

export default connect<IIndexState, IIndexDispatch, IIndexProps>(stateToProps, {
    setTitle,
    saveTodo,
    setDone,
})(IndexView);

First we define a function to transform our State into the IIndexState required by our IndexView

import { State } from '../../redux/reducer';
import { IIndexState } from './IndexView';

const stateToProps = (state: State): IIndexState => ({
    title: state.index.title,
    todos: state.index.todos,
    loading: state.index.loading,
});

where we get the required information from the State and return it with the correct key.


Thanks to a shorthand in react-redux we can just define the actions we need in the component by putting them in an object as the second argument for connect

import { connect } from 'react-redux';
import { setTitle, saveTodo, setDone } from './IndexReducer';
import { IIndexState, IIndexDispatch, IIndexProps } from './IndexView';

export default connect<IIndexState, IIndexDispatch, IIndexProps>(stateToProps, {
    setTitle,
    saveTodo,
    setDone,
})

where connect uses internally the function bindActionCreators for each action in the object and passes them on as functions that dispatch automatically. They will be named the same as they are in the object, so for example setTitle will be accessible as this.props.setTitle in the component.


Finally we bind it all using react-redux's connect

import { connect } from 'react-redux';
import { setTitle, saveTodo, setDone } from './IndexReducer';
import IndexView, { IIndexState, IIndexDispatch, IIndexProps } from './IndexView';

const stateToProps = ...

export default connect<IIndexState, IIndexDispatch, IIndexProps>(stateToProps, {
    setTitle,
    saveTodo,
    setDone,
})(IndexView);

where the first type argument is the type for the format we want to transform our state to (in this case our IIndexState), the second type argument is the format we want to transform the dispatch-function to (in this case our IIndexDispatch) and the last type argument is the type for the props our view expects. The first argument connect takes is a function to transform our state into the type of the first type argument and the second argument is a function to transform the dispatch-function into the second type argument (here we also see for the first time a curried function). The last argument is our view itself, which should be expecting props of the type of the third type argument.

results matching ""

    No results matching ""