Skip to content

iyegoroff/with-context-selector

Repository files navigation

with-context-selector

npm build publish codecov Type Coverage Libraries.io dependency status for latest release Bundlephobia npm

Generic React context selector HOC

Getting started

npm i with-context-selector

Usage

Singular context selector:

import { withContextSelector } from 'with-context-selector'

const foo = { x: 1, y: 2 }
const FooContext = React.createContext(foo)

// context can have a displayName
FooContext.displayName = 'FooContext'

const ConnectedFoo = withContextSelector(
  FooContext,
  // FooContext triggers Foo rerender only when x prop is updated
  () =>
    ({ x, y }) => ({ x }),
  function Foo({ x, z }: { x: number; z: number }) {
    return <div>{x + z}</div>
  }
)

// ConnectedFoo requires only z prop, x prop is provided by context
const App = (
  <FooContext.Provider value={foo}>
    <ConnectedFoo z={3} />
  </FooContext.Provider>
)

Multiple context selector:

import { withContextSelector } from 'with-context-selector'

const foo = { x: 1, y: 2 }
const bar = 'bar'
const FooContext = React.createContext(foo)
const BarContext = React.createContext(bar)

const ConnectedFooBar = withContextSelector(
  [FooContext, BarContext],
  () => (foo, bar) => ({ foo: foo.x, bar }),
  function FooBar({ foo, bar }: { foo: number, bar: string }) {
    return <div>{String(foo) + bar}</div>
  }
)

const App = (
  <FooContext.Provider value={foo}>
    <BarContnext.Provider value={bar}>
      <ConnectedFooBar />
    </BarContnext.Provider
  </FooContext.Provider>
)

Passing props to selector:

import { withContextSelector } from 'with-context-selector'

const foo = { x: 1, y: 2 }
const FooContext = React.createContext(foo)

const ConnectedFoo = withContextSelector(
  FooContext,
  // Extra props for selector and resulting component
  ({ select }: { select: 'x' | 'y' }) =>
    (props) => ({ x_or_y: props[select] }),
  function Foo({ x_or_y, z }: { x_or_y: number; z: number }) {
    return <div>{x_or_y + z}</div>
  }
)

// ConnectedFoo requires only z prop, x prop is provided by context
const App = (
  <FooContext.Provider value={foo}>
    {/* will render: 4 */}
    <ConnectedFoo select={'x'} z={3} />

    {/* will render: 5 */}
    <ConnectedFoo select={'y'} z={3} />
  </FooContext.Provider>
)

About

Generic React context selector HOC

Resources

License

Stars

Watchers

Forks

Packages

No packages published