# React Retux
Note that you can write Containers with react-redux
as usual. But if you want extra type strictness, missing-props checking and better auto-completion, give React Retux (opens new window) a try.
React Retux (opens new window) is a type enhancement suite which contains no JavaScript code. It does not rely on Retux architecture and can be used on its own.
# Extract Dispatchers
First pick props properties that will dispatch Redux Actions.
// src/containers/FilterLink.tsx
import { ExtractDispatchers } from 'react-retux'
import { Link, LinkProps } from '../components/Link'
type Dispatchers = ExtractDispatchers<LinkProps, 'setFilter'>
# Map State To Props
// src/containers/FilterLink.tsx
import { ExtractDispatchers, MapStateToProps } from 'react-retux'
import { PropsWithChildren } from 'react'
import { StoreState, StoreAction } from '../retux-store'
import { Link, LinkProps } from '../components/Link'
type Dispatchers = ExtractDispatchers<LinkProps, 'setFilter'>
// Own Props
export interface FilterLinkProps {
filter: VisibilityFilter
}
const mapStateToProps: MapStateToProps<
StoreState,
LinkProps,
Dispatchers,
PropsWithChildren<FilterLinkProps>
> = (state, ownProps) => ({
active: ownProps.filter === state.visibilityFilter
})
# Map Dispatch To Props
There are two types of MapStateToProps
in React Redux.
# Function Form
import { connect } from 'react-redux'
import {
ExtractDispatchers,
MapStateToProps,
MapDispatchToProps
} from 'react-retux'
import { action } from '../retux-store/actions'
import { Link, LinkProps } from '../components/Link'
import { StoreState, StoreAction } from '../retux-store'
import { VisibilityFilter } from '../utilities/visibility'
import { PropsWithChildren } from 'react'
type Dispatchers = ExtractDispatchers<LinkProps, 'setFilter'>
export interface FilterLinkProps {
filter: VisibilityFilter
}
const mapStateToProps: MapStateToProps<
StoreState,
LinkProps,
Dispatchers,
PropsWithChildren<FilterLinkProps>
> = (state, ownProps) => ({
active: ownProps.filter === state.visibilityFilter
})
const mapDispatchToProps: MapDispatchToProps<
StoreAction,
LinkProps,
Dispatchers,
PropsWithChildren<FilterLinkProps>
> = (dispatch, ownProps) => ({
setFilter: () => {
dispatch(action.VisibilityFilterSet(ownProps.filter))
}
})
export default connect(mapStateToProps, mapDispatchToProps)(Link)
# Object Form
import { connect } from 'react-redux'
import {
ExtractDispatchers,
MapStateToProps,
MapDispatchToProps
} from 'react-retux'
import { StoreState, StoreAction } from '../retux-store'
import { action } from '../retux-store/actions'
import { MainSection, MainSectionProps } from '../components/MainSection'
type Dispatchers = ExtractDispatchers<
MainSectionProps,
'completeAllTodos' | 'clearCompleted'
>
const mapDispatchToProps: MapDispatchToProps<
StoreAction,
MainSectionProps,
Dispatchers
> = {
completeAllTodos: action.TODOS$COMPLETE_ALL,
clearCompleted: action.TODOS$CLEAR_COMPLETED
}
# Mixed Action Types
If you use middlewares like Redux Thunk or Redux Promise which introduce mixed Action types, you need to use the more primitive MapDispatchToPropsFunction
or MapDispatchToPropsObject
.
See Redux Thunk and Redux Promise for more details.