Search code examples
javascriptreactjsrecompose

Using recompose branch within a React container component


I have a container component for a modal. It imports LabelDetailForm, which is adds the modal's content to the page using React portals.

import {compose, branch} from 'recompose'
import {actionCreators as uiActionCreators} from '../../redux/reducers/ui/uiActions'
import {connect} from 'react-redux'
import LabelDetailForm from '../../forms/labelDetail/labelDetailForm'

export function mapStateToProps (state, props) {
    return {
        showModal: state.ui.showLabelDetailModal
    }
}

export const mapDispatchToProps = (dispatch, ownProps) => {
    return {
        closeModal: () => {
            dispatch(uiActionCreators.toggleLabelDetailModal())
        }
    }
}

export default compose(
    connect(mapStateToProps, mapDispatchToProps)
)(LabelDetailForm)

LabelDetailForm can prevent the modal's contents from appearing in the DOM by checking the value of props.showModal in it's render method. However, according to the React Developer Tools extension for Chrome, the LabelDetailForm component always exists. To save memory, I want the container component to only export LabelDetailForm when showModal is true.

I tried to use branch():

export default compose(
    connect(mapStateToProps, mapDispatchToProps),
    branch(
        ({ showModal }) => showModal,
        LabelDetailForm,
        null
    )
)

However, the LabelDetailForm never appears even when showModal is true and I get the following warning in the console:

Warning: Functions are not valid as a React child.

Solution

  • The second and third arguments of branch() are higher-order components, instead of components or null. You can use renderComponent() and renderNothing() to create the HOCs:

    branch(
      ({ showModal }) => showModal,
      renderComponent(LabelDetailForm),
      renderNothing
    )