Last active
September 30, 2018 04:23
-
-
Save Sawtaytoes/c211a01fc3bc8b5c2b01110fb1297ec4 to your computer and use it in GitHub Desktop.
A complex example of using `connect` with its failure situations compared to `ReduxConnection`:
- You use mapDispatchToProps.
- You stack higher-order components such as connect and reduxForm.
- You have to combine two or more state selectors for one
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
) | |
) | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment