A complex example of using connect
with its failure situations compared to ReduxConnection
:
import CheckCircleIcon from '@material-ui/icons/CheckCircle'
import CircleIcon from '@material-ui/icons/Circle'
import List from '@material-ui/core/List'
import ListItem from '@material-ui/core/ListItem'
import ListItemIcon from '@material-ui/core/ListItemIcon'
import ListItemText from '@material-ui/core/ListItemText'
import PropTypes from 'prop-types'
import React, { Fragment } from 'react'
import { connect } from 'react-redux'
import { push } from 'connected-react-router'
import { withStyles } from '@material-ui/core/styles'
import SectionHeading from '~/components/siteLayout/SectionHeading'
import { listItemsSelector } from '~/redux/lists/selectors'
import { sectionsSelector } from '~/redux/sections/selectors'
const propTypes = {
namespace: PropTypes.string.isRequired, // Used by Redux `connect` to lookup items
personLocation: PropTypes.string.isRequired,
// Material-UI Styles
classes: PropTypes.object.isRequired,
// Redux
listItems: (
PropTypes
.arrayOf(
PropTypes
.shape({
id: PropTypes.string.isRequired,
isChecked: PropTypes.bool,
name: PropTypes.string.isRequired,
})
.isRequired
)
.isRequired
),
push: PropTypes.func.isRequired,
sectionLink: PropTypes.string.isRequired,
sectionTitle: PropTypes.string.isRequired,
}
export const PersonsList = ({
classes,
listItems,
personLocation,
push,
sectionLink,
sectionTitle,
}) => (
<Fragment>
<SectionHeading href={sectionLink}>
{sectionTitle}
</SectionHeading>
<List className={classes.list}>
{
listItems
.map(({
id,
isChecked,
name,
}) => (
<ListItem key={id}>
<ListItemIcon>
{
isChecked
? (
<CheckCircleIcon
className={
classes
.checkmarkIcon
}
/>
)
: <CircleIcon />
}
</ListItemIcon>
<ListItemText
onClick={
push(
personLocation
.concat('/')
.concat(id)
)
}
>
{name}
</ListItemText>
</ListItem>
))
}
</List>
</Fragment>
)
PersonsList
.propTypes = propTypes
const styles = ({ palette }) => ({
checkmarkIcon: {
color: palette.primary.main,
},
list: {
backgroundColor: 'white',
border: `solid 1px ${palette.primary.main}`,
color: palette.primary.main,
fontSize: '1em',
fontWeight: '500',
height: '1.5em',
width: '1.5em',
},
})
const mapStateToProps = (state, { namespace }) => ({
...(
listItemsSelector(
state,
{ namespace },
)
),
...(
sectionsSelector(
state,
{ namespace },
)
),
})
const mapDispatchToProps = {
push,
}
export default (
connect(
mapStateToProps,
mapDispatchToProps,
)(
withStyles(
styles
)(
PersonsList
)
)
)
import CheckCircleIcon from '@material-ui/icons/CheckCircle'
import CircleIcon from '@material-ui/icons/Circle'
import List from '@material-ui/core/List'
import ListItem from '@material-ui/core/ListItem'
import ListItemIcon from '@material-ui/core/ListItemIcon'
import ListItemText from '@material-ui/core/ListItemText'
import PropTypes from 'prop-types'
import React, { Fragment } from 'react'
import { MaterialUiStyles } from 'imagined-material-ui-styles-component'
import { push } from 'connected-react-router'
import { ReduxConnection } from '@ghadyani-framework/redux-components'
import SectionHeading from '~/components/siteLayout/SectionHeading'
import { listItemsSelector } from '~/redux/lists/selectors'
import { sectionsSelector } from '~/redux/sections/selectors'
const propTypes = {
namespace: PropTypes.string.isRequired,
personLocation: PropTypes.string.isRequired,
}
const styles = ({ palette }) => ({
checkmarkIcon: {
color: palette.primary.main,
},
list: {
backgroundColor: 'white',
border: `solid 1px ${palette.primary.main}`,
color: palette.primary.main,
fontSize: '1em',
fontWeight: '500',
height: '1.5em',
width: '1.5em',
},
})
const PersonsList = ({
namespace,
personLocation,
}) => (
<Fragment>
<ReduxConnection
namespace={namespace}
selector={sectionsSelector}
>
{({
sectionLink,
sectionTitle,
}) => (
<SectionHeading href={sectionLink}>
{sectionTitle}
</SectionHeading>
)}
</ReduxConnection>
<MaterialUiStyles styles={styles}>
{({ classes }) => (
<List className={classes.list}>
<ReduxConnection
namespace={namespace}
selector={listItemsSelector}
>
{({ listItems }) => (
listItems
.map(({
id,
isChecked,
name,
}) => (
<ListItem key={id}>
<ListItemIcon>
{
isChecked
? (
<CheckCircleIcon
className={
classes
.checkmarkIcon
}
/>
)
: <CircleIcon />
}
</ListItemIcon>
<ReduxConnection>
{({ dispatch }) => (
<ListItemText
onClick={
dispatch(
push(
personLocation
.concat('/')
.concat(id)
)
)
}
>
{name}
</ListItemText>
)}
</ReduxConnection>
</ListItem>
))
)}
</ReduxConnection>
</List>
)}
</MaterialUiStyles>
</Fragment>
)
PersonsList
.propTypes = propTypes
export default PersonsList