pgarciacamou / react-context-consumer-hoc

HOC that consumes multiple contexts and pass as props to components
MIT License
18 stars 3 forks source link
context context-props hoc react

react-context-consumer-hoc v2.x

React context consumer hoc. A 2KB lib that consumes context as props.

NPM JavaScript Style Guide Build Status Package Quality Renovate

Install

npm install --save react-context-consumer-hoc

Documentation

The Gist

Using withContextAsProps

import { withContextAsProps } from 'react-context-consumer-hoc'

// ContextA == { a: 1 } && ContextB == { b: 1 }
const InnerComponent = ({ a, b, ...ownProps }) => { /* ... */ }
const MyComponent = withContextAsProps(ContextA, ContextB)(InnerComponent)

Using withContext

import { withContext } from 'react-context-consumer-hoc'

// ContextA == { a: 1 } && ContextB == { b: 1 }
const InnerComponent = ({ c, ...ownProps }) => { /* ... */ }
const MyComponent = withContext(
  [ContextA, ContextB],
  (context, ownProps) => ({ c: context.a + context.b }) // mapContextToProps
)(InnerComponent)

Using withContext and reselect -> createSelector()

import { withContext } from 'react-context-consumer-hoc'
import { createSelector } from 'reselect'

const addAandB = createSelector(
  (context) => context.a,
  (context) => context.b,
  (a, b) => a + b
)

// ContextABC == { a: 1, b: 2, c: 3 }
const InnerComponent = ({ sum, ...ownProps }) => { /* ... */ }
const MyComponent = withContext(
  [ContextABC],
  (context, ownProps) => ({ sum: addAandB(context) }) // mapContextToProps
)(InnerComponent)

Namespaces using withContext and reselect -> createStructuredSelector()

import { withContext } from 'react-context-consumer-hoc'
import { createStructuredSelector } from 'reselect'

// ContextA == { a: 1 } && ContextB == { b: 1 }
const InnerComponent = ({ context: { a, b }, ...ownProps }) => { /* ... */ }
const MyComponent = withContext(
  [ContextA, ContextB],
  createStructuredSelector({
    context: createStructuredSelector({
      a: (context) => context.a,
      b: (context) => context.b
    })
  })
)(InnerComponent)

API

withContextAsProps

withContextAsProps(Context1[, Context2, ..., ContextN])(Component)

Wraps the Component with dynamically created consumers and passes all consumed context as props. withContextAsProps is a facade around withContext, providing a convenient API for the most common use cases.

Arguments

withContext

withContext(contextList, mapContextToProps)(Component)

Wraps the Component with dynamically created consumers and passes all consumed context as props.

Arguments

Full example

// ProviderA.js
import React from 'react'
const childContextA = { a: 1 }
export const ContextA = React.createContext(childContextA)
export default ({ children }) => (
  <ContextA.Provider value={childContextA}>
    {children}
  </ContextA.Provider>
)

// ProviderB.js
import React from 'react'
const childContextB = { b: 2 }
export const ContextB = React.createContext(childContextB)
export default ({ children }) => (
  <ContextB.Provider value={childContextB}>
    {children}
  </ContextB.Provider>
)

// MyComponent.js
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { withContextAsProps } from 'react-context-consumer-hoc'
import { ContextA } from './ProviderA'
import { ContextB } from './ProviderB'

class MyComponent extends Component {
  static propTypes = {
    // from context
    a: PropTypes.number.isRequired,
    b: PropTypes.number.isRequired,

    // own props
    c: PropTypes.number.isRequired
  }

  render() {
    return (
      <div>
        <div>{this.props.a}</div>
        <div>{this.props.b}</div>
        <div>{this.props.c}</div>
      </div>
    )
  }
}

export default withContextAsProps(ContextA, ContextB)(MyComponent)

// App.js
import React, { Component } from 'react'
import ProviderA from './ProviderA'
import ProviderB from './ProviderB'
import MyComponent from './MyComponent'

export default class App extends Component {
  render () {
    return (
      <ProviderA>
        <ProviderB>
          <div className='stuff'>some other content</div>
          <div className='nested element'>
            <MyComponent c="3" />
          </div>
        </ProviderB>
      </ProviderA>
    )
  }
}

Author

Contributors

pablo garcia
pablo garcia
💻 📖 💡

This project follows the all-contributors specification.

Package Quality