npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-connect-context-map

v1.1.1

Published

> This is a fork of [https://github.com/contiamo/react-connect-context](react-connect-context).

Downloads

284

Readme

react-connect-context-map

This is a fork of https://github.com/contiamo/react-connect-context.

This module exports a function factory that produces an HOC to wrap a component and provide the value of the context as props to the component, much like the react-redux API. The benefits of this approach versus the traditional Consumer:

  • All values are passed as props and can be read in your component's lifecycle methods
  • You can trivially export a "pure" version of the component as well as a connected version
  • Unlike a Redux container, the connected component can be rendered without being nested in a Provider component
  • The factory produces an HOC which can be applied to multiple components
  • You can select slices of the context value and map them to props that fit the component API
  • You can reference the props passed into the connected component when mapping the context value to props
  • You can customize the merging behavior to translate all props fed to the wrapped component

Getting Started

  1. yarn add react-connect-context-map
  2. At the top of your file, import { connectContext } from "react-connect-context-map"
  3. Wrap your component in the function as so: connectContext(Context.Consumer)(MyComponent)

Examples

Introductory example

import React from "react"
import { render } from "react-dom"
import { connectContext } from "react-connect-context-map"

// The shape of the context value
interface ContextType {
  color: string
}

// The shape of the props passed to your component
interface MergedPropsType extends ContextType {
  children: React.ReactNode
  myProp: string
}

// Create a new React Context instance
const Context = React.createContext<ContextType>({ color: "red" })

// Create an HOC for connecting your component to context
const createContainer = connectContext<ContextType>(Context.Consumer)

// The connected component will receive the props passed in as well as values
// from the context object by default
const Content: React.SFC<MergedPropsType> = ({ children, color, myProp }) => (
  <div>
    <p>{children}</p>
    <div>
      I have looked into context and I've seen the color is:
      <span style={{ color }}>
        <strong>{color}</strong>
      </span>! I also get my own props like <strong>{myProp}</strong>!
    </div>
  </div>
)

// Call the HOC on the component to connect it to context
const ConnectedContent = createContainer<MergedPropsType>(Content)

const App: React.SFC = () => (
  <div className="demo">
    <ConnectedContent myProp="THIS IS MY PROP, HI!">
      Hello! I've written this component so that Magical Context-based text
      appears after children!
    </ConnectedContent>
  </div>
)

// Render the connected components in the provider
render(
  <Context.Provider value={{ color: "red" }}>
    <App />
  </Context.Provider>,
  document.querySelector("#root")
)

Mapping context properties to props

This example shows how a context value can be mapped to a different prop name or value.

import React from "react"
import { render } from "react-dom"
import { connectContext } from "react-connect-context-map"

interface ContextType {
  color: string
}

// The shape of the props that have been derived from context
interface ContextPropsType {
  isRed: boolean
}

// The shape of the props that are not derived from context and may be
// passed to the connected component
interface OwnPropsType {
  myProp: string
}

// The shape of the props passed to the connected component
interface MergedPropsType extends ContextPropsType, OwnPropsType {}

const Context = React.createContext<ContextType>({ color: "red" })

const Content: React.SFC<MergedPropsType> = ({ isRed, myProp }) => (
  <p>This pen {isRed ? "is" : "is not"} red. My prop is {myProp}.</p>
)

// ContextPropsType can be used when the result of mapContextToProps does
// not match the shape of ContextType
const createContainer = connectContext<ContextType, ContextPropsType>(
  Context.Consumer,
  context => ({
    isRed: context.color === "red"
  })
)

// OwnPropsType can be used to define the props on the wrapped component
// when additional props not inferred from context are provided
const ConnectedContent = createContainer<
  MergedPropsType,
  OwnPropsType
>(Content)

render(
  <Context.Provider value={{ color: "red" }}>
    <App />
  </Context.Provider>,
  document.querySelector("#root")
)

Customizing prop merging

This example shows how you can customize the merge behavior. Here we even map a non-context prop to another key.

import React from "react"
import { render } from "react-dom"
import { connectContext } from "react-connect-context-map"

interface ContextType {
  color: string
}

interface OwnPropsType {
  theProp: string
}

interface MergedPropsType extends ContextType, OwnPropsType {}

const Context = React.createContext<ContextType>({ color: "red" })

const Content: React.SFC<MergedPropsType> = ({ color, theProp }) => (
  <p>This pen {isRed ? "is" : "is not"} red. My prop is {theProp}.</p>
)

const createContainer = connectContext<ContextType>(
  Context.Consumer,
  null,
  // Merge context properties into props and translate myProp to theProp
  (context, props) => ({
    ...context,
    theProp: props.myProp
  })
)

const ConnectedContent = createContainer<
  MergedPropsType,
  OwnPropsType
>(Content)

render(
  <Context.Provider value={{ color: "red" }}>
    <App />
  </Context.Provider>,
  document.querySelector("#root")
)

Using non-object context values with mapContextToProps

This example shows how you can allow for non-object context values if you provide a custom mapContextToProps function.

import React from "react"
import { render } from "react-dom"
import { connectContext } from "react-connect-context-map"

// Context value is not an object
type ContextType = string

interface ContextPropsType {
  color: string
}

interface OwnPropsType {
  myProp: string
}

interface MergedPropsType extends ContextPropsType, OwnPropsType {}

const Context = React.createContext<ContextType>({ color: "red" })

const Content: React.SFC<MergedPropsType> = ({ color, theProp }) => (
  <p>This pen {isRed ? "is" : "is not"} red. My prop is {theProp}.</p>
)

const createContainer = connectContext<
  ContextType,
  ContextPropsType
>(
  Context.Consumer,
  // Context value is mapped to an object that conforms to
  // ContextPropsType
  context => ({ color: context })
)

const ConnectedContent = createContainer<
  MergedPropsType,
  OwnPropsType
>(Content)

render(
  <Context.Provider value="red">
    <App />
  </Context.Provider>,
  document.querySelector("#root")
)

API

connectContext

Factory function that creates a container component HOC to consume context Context and map values to match ContextProps.

connectContext<Context, ContextProps extends Object = Context>(
  // The React Consumer component.
  ContextConsumer: React.Consumer<Context>,

  // A function that maps the consumed context value to props to pass to
  // the component. The default function requires the context value to be
  // an object and maps its properties to component props.
  mapContextToProps: MapContextToProps<Context, ContextProps, OwnProps>
    = context => context,

  // A function that merges the props that have been mapped from context
  // values with the props passed to the connected component. The default
  // function merges context props with the passed props, with the latter
  // overwriting the former.
  mergeProps: MergeProps<ContextProps, OwnProps, MergedProps> =
    (contextProps, ownProps) => ({ ...contextProps, ...ownProps })
): createContainer // HOC to connect a component.

createContainer

An HOC that returns a connected component that accepts props OwnProps and derives ContextProps to merge into MergedProps. It returns a component that accepts OwnProps as props and renders the given component with MergedProps.

createContainer<MergedProps extends ContextProps, OwnProps = Partial<MergedProps>>(
  // The component to connect.
  Component: React.SFC<MergedProps>
): React.SFC<OwnProps> // The container component.

MapContextToProps

A function type that maps the consumed context value Context and props passed to the connected component OwnProps to a subset of the props that can be derived from context ContextProps, to pass to the component.

type MapContextToProps<Context, ContextProps, OwnProps> = (
  // The consumed context value.
  context: Context,

  // The props passed to the connected component.
  ownProps: OwnProps
) => ContextProps // The props derived from context.

MergeProps

A function type that merges the props that have been mapped from context ContextProps with the props passed to the connected component OwnProps to return all the props MergedProps, to pass to the wrapped component.

type MergeProps<ContextProps, OwnProps, MergedProps> = (
  // The result of `mapContextToProps`.
  contextProps: ContextProps,

  // The props passed to the connected component.
  ownProps: OwnProps
) => MergedProps // The props to pass to the given component.

Frequently Asked Questions

Can I pick state and only re-render when necessary?

Sure. Consider using PureComponent or shouldComponentUpdate to let your components know when or when not to update.

Additionally, unlike Redux, React 16.3 allows the creation of multiple, composable Contexts, so ideally, you'd be using a Context that is small enough to house just the information that you'd like to reuse in order to properly separate concerns and correctly use the principle of least privilege when passing context around.


Made with ❤️ at Contiamo in Berlin.