Mitch Masia
Building awesome products using React, React Native, GraphQL, and Elixir.
// Function that returns a comparator function
const isMultipleOfX = x =>
candidate => candidate % x === 0
// Checks if number is a multiple of 3
const isMultipleOf3 = isMultipleOfX(3)
isMultipleOf3(12) // true
// Checks if a number is a multiple of 5
const isMultipleOf5 = isMultipleOfX(5)
isMultipleOf5(15) // true
const sumPure = (x, y) => x + y
const Header = props => <h1>{props.content}</h1>
const enhancer = BaseComponent =>
class Wrapper extends Component {
render() {
return <BaseComponent {...this.props} />
}
}
const withTitle = BaseComponent =>
class Wrapper extends Component {
render() {
return (
<div>
<h1>Here is a title</h1>
<BaseComponent {...this.props} />
</div>
}
}
const withTitle = title => BaseComponent =>
class Wrapper extends Component {
render() {
return (
<div>
<h1>{title}</h1>
<BaseComponent {...this.props} />
</div>
}
}
const withMountingAction = BaseComponent =>
class Wrapper extends Component {
componentDidMount() {...}
render() {
return <BaseComponent {...this.props} />
}
}
import withMountingAction from './withMountingAction'
const Header = props => (<h1>{props.content}</h1>)
export default withMountingAction(Header)
Recompose is a React utility belt for function components and higher-order components. Think of it like lodash for React.
<recompose_function>(config) => BaseComp => EnhancedComp
import React, { Component } from 'react'
import PropTypes from 'prop-types'
export default class Header extends Component {
static propTypes = {
content: PropTypes.string.isRequired,
}
render() {
return <h1>{this.props.content}</h1>
}
}
import React, { Component } from 'react'
import { setPropTypes } from 'recompose'
import PropTypes from 'prop-types'
class Header extends Component {
render() {
return <h1>{this.props.content}</h1>
}
}
// Create enhancer
const withPropTypes = setPropTypes({
content: PropTypes.string.isRequired,
})
export default withPropTypes(Header)
import React from 'react'
import { setPropTypes } from 'recompose'
import PropTypes from 'prop-types'
const Header = props => (<h1>{props.content}</h1>)
const withPropTypes = setPropTypes({
content: PropTypes.string.isRequired,
})
export default withPropTypes(Header)
import React, { Component } from 'react'
import PropTypes from 'prop-types'
export default class Header extends Component {
static propTypes = {
content: PropTypes.string.isRequired,
}
static defaultProps = {
content: 'Hello, world!',
}
render() {
return <h1>{this.props.content}</h1>
}
}
import React from 'react'
import { defaultProps, setPropTypes } from 'recompose'
import PropTypes from 'prop-types'
const Header = props => (<h1>{props.content}</h1>)
const withPropTypes = setPropTypes({
content: PropTypes.string.isRequired,
})
const withDefaultProps = defaultProps({
content: 'Hello, world!',
})
export default withPropTypes(withDefaultProps(Header))
import React from 'react'
import { compose, defaultProps, setPropTypes } from 'recompose'
import PropTypes from 'prop-types'
const Header = props => (<h1>{props.content}</h1>)
const withPropTypes = setPropTypes({
content: PropTypes.string.isRequired,
})
const withDefaultProps = defaultProps({
content: 'Hello, world!',
})
export default compose(
withDefaultProps,
withPropTypes
)(Header)
compose(withDefaultProps, withPropTypes)(Header)
// is the same as this; HOCs are applied LTR
withPropTypes(withDefaultProps(Header))
import React from 'react'
import { FlatList } from 'react-native'
const CustomList = props => <FlatList {...props} />
export default CustomList
import React from 'react'
import { compose, setPropTypes } from 'recompose'
import { FlatList } from 'react-native'
const CustomList = props => <FlatList {...props} />
// Enhancers
const withPropTypes = setPropTypes({
data: PropTypes.array.isRequired,
})
export default compose(withPropTypes)(CustomList)
import React from 'react'
import { compose, defaultProps, setPropTypes } from 'recompose'
import { FlatList } from 'react-native'
const CustomList = props => <FlatList {...props} />
// Enhancers
const withPropTypes = setPropTypes({
data: PropTypes.array.isRequired,
})
const withDefaultProps = defaultProps({
data: [],
})
export default compose(withDefaultProps, withPropTypes)(CustomList)
import React from 'react'
import { branch, compose, defaultProps, renderNothing, setPropTypes } from 'recompose'
import { FlatList } from 'react-native'
const CustomList = props => <FlatList {...props} />
// Enhancers
const withPropTypes = setPropTypes({
data: PropTypes.array.isRequired,
})
const withDefaultProps = defaultProps({
data: [],
})
const withEmptyState = branch(
ownProps => !ownProps.data.length,
renderNothing(),
)
export default compose(
withDefaultProps,
withEmptyState,
withPropTypes,
)(CustomList)
compose(
withDefaultProps,
withEmptyState,
withPropTypes,
)(CustomList)
compose(
withDefaultProps,
withEmptyState,
withPropTypes,
)(CustomList)
import React from 'react'
import { compose, pure } from 'recompose'
import { FlatList } from 'react-native'
const CustomList = props => <FlatList {...props} />
export default compose(pure)(CustomList)
import React from 'react'
import { compose, onlyUpdateForKeys } from 'recompose'
import { FlatList } from 'react-native'
const CustomList = props => <FlatList {...props} />
// Enhancers
const withPropComparator = onlyUpdateForKeys(['data'])
export default compose(withPropComparator)(CustomList)
import React from 'react'
import { compose, shouldUpdate } from 'recompose'
import { FlatList } from 'react-native'
const CustomList = props => <FlatList {...props} />
// Enhancers
const withPropComparator = shouldUpdate(
(currentProps, nextProps) => {...}
)
export default compose(withPropComparator)(CustomList)
import React, { Component } from 'react'
const withMountingAction = BaseComponent =>
class Wrapper extends Component {
componentDidMount() {...}
render() {
return <BaseComponent {...this.props} />
}
}
import { lifecycle } from 'recompose'
const withMountingAction = lifecycle({
componentDidMount() {...}
})
export default withMountingAction
By Mitch Masia
Functional programming with React
Building awesome products using React, React Native, GraphQL, and Elixir.