All Projects → troch → react-zap

troch / react-zap

Licence: MIT license
⚡ Zap props from one React component to another, using React new context API and your existing higher-order components ⚡

Programming Languages

typescript
32286 projects
javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to react-zap

React Workshop
⚒ 🚧 This is a workshop for learning how to build React Applications
Stars: ✭ 114 (+570.59%)
Mutual labels:  context, higher-order-component
react-table-hoc-draggable-columns
ReactTable HOC for draggable columns
Stars: ✭ 27 (+58.82%)
Mutual labels:  higher-order-component
Contextism
😍 Use React Context better.
Stars: ✭ 141 (+729.41%)
Mutual labels:  context
react-listener-provider
Create a ReactListenerProvider and use HOC (Higher Order Components) to listen for Events in one place.
Stars: ✭ 19 (+11.76%)
Mutual labels:  higher-order-component
Preact Context
React new Context API for preact
Stars: ✭ 154 (+805.88%)
Mutual labels:  context
redux-autoloader
A higher order component for declarative data loading in React and Redux.
Stars: ✭ 56 (+229.41%)
Mutual labels:  higher-order-component
Pex Context
Modern WebGL state wrapper for PEX: allocate GPU resources (textures, buffers), setup state pipelines and passes, and combine them into commands.
Stars: ✭ 117 (+588.24%)
Mutual labels:  context
elcontext
Context-based actions for Emacs
Stars: ✭ 18 (+5.88%)
Mutual labels:  context
ember-right-click-menu
An easy and flexible addon to add context menus anywhere in your application
Stars: ✭ 14 (-17.65%)
Mutual labels:  context
react-app-loader
Production ready library for handling Microfrontends
Stars: ✭ 75 (+341.18%)
Mutual labels:  higher-order-component
ghaction-dump-context
GitHub Action composite to dump context
Stars: ✭ 30 (+76.47%)
Mutual labels:  context
Timber Ruby
🌲 Great Ruby logging made easy.
Stars: ✭ 154 (+805.88%)
Mutual labels:  context
rrx
⚛️ Minimal React router using higher order components
Stars: ✭ 69 (+305.88%)
Mutual labels:  higher-order-component
React Af
Allows you to code using certain React.next features today! Perfect for component library maintainers.
Stars: ✭ 143 (+741.18%)
Mutual labels:  context
interactor
Simple service objects for PHP
Stars: ✭ 36 (+111.76%)
Mutual labels:  context
Ngx Context
Angular Context: Easy property binding for router outlet and nested component trees.
Stars: ✭ 118 (+594.12%)
Mutual labels:  context
Timber Elixir
🌲 Great Elixir logging made easy
Stars: ✭ 226 (+1229.41%)
Mutual labels:  context
react-context
(つ°ヮ°)つ Understanding React Context
Stars: ✭ 11 (-35.29%)
Mutual labels:  context
context
A proof of concept implementation of scoped context
Stars: ✭ 16 (-5.88%)
Mutual labels:  context
Dapper.AmbientContext
Ambient context implementation for Dapper.NET
Stars: ✭ 31 (+82.35%)
Mutual labels:  context

npm version License: MIT Build Status styled with prettier

react-zap

Zap props from one React component to another!

Why?

React's new context API allows you to send data from one component to any component in its tree of children. React-zap lets you tie this powerful new feature in to the similarly powerful concept of higher-order components!

HoCs and Render Props?

One aspect of the new context API which has been much talked about in the community is that it uses the function-as-a-child pattern (also called render props) for its Consumers. This pattern has been positioned by some as an alternative to higher-order components, so the general impression is that you need to choose: either use HoCs or use Render Props.

However, the API is about sharing dynamic context, not about render functions. The ability to pass data directly to any child is applicable to many situations; the method with which you access this data is not relevant to the feature. And in fact, this feature can be combined with higher-order components to make it even more powerful!

HoCs are not dead! This package allows you to use your trusted and useful HoCs and to plug them into React's new context API.

This package offers two higher-order components: propsToContext to populate a context provider with existing props, and contextToProps if you prefer to consume context with a HoC (for example within a compose function).

API

propsToContext(Provider, config?)(BaseComponent)

Wraps your component with the specified Provider, and sends the component's props into context. By default, all props will be included in context; you can optionally define a list of props to include, or a function to map the props manually.

  • Provider: a React context provider, returned by React.createContext
  • config:
    • An array of prop keys to sent to context.

      Example: propsToContext(Provider, ['propToInclude'])(Component)

    • A function mapping props to context.

      Example: propsToContext(Provider, ({ propToIgnore, ...otherProps }) => otherProps)(Component)

contextToProps(Consumer, config?)(BaseComponent)

Wraps your component with the specified Consumer, and sends the context into its props. By default, the context will be spread into the component's props; you can optionally define a prop key for the context object, or a function to map to props manually.

  • Consumer: a React context consumer, returned by React.createContext
  • config (optional):
    • A string, to be used as a prop key for the context object.

      Example: contextToProps(Consumer, 'allContext')(Component)

    • A function mapping context to props.

      Example: contextToProps(Consumer, ({ contextToIgnore, ...otherContexts }) => otherContexts)(Component)

Examples

With a state HOC

Using react-state-hoc. We will first create our context components:

import React from 'react'

const initialState = {
    visible: false
}

const {
    Provider: StateProvider,
    Consumer: StateConsumer
} = React.createContext(initialState)

export { initialState, StateProvider, StateConsumer }

Given an imaginary ViewComponent, we will set our state in context using propsToContext. Note the use of a compose function to compose our different higher-order components, provided by some libraries like redux (you can write your own!)

import React from 'react'
import { propsToContext } from 'react-zap'
import { withState } from 'react-state-hoc'

import { initialState, StateProvider } from './context'
import ViewComponent from './ViewComponent'

export default compose(
    withState(initialState, {
        setVisibility: visible => ({ visible })
    })
    propsToContext(StateProvider, [ 'visible', 'setVisibility' ])
)(ViewComponent)

Now the state in withState will be added to our provider. Note that we have whitelisted props 'visible' and 'setVisibility'. To consume it, given ToggleButton and Toggle components mounted somewhere deep in ViewComponent:

import React from 'react'
import { contextToProps } from 'react-zap'
import { StateConsumer } from './context'

const withState = contextToProps(StateConsumer)

const ToggleButton = ({ setVisibility }) => (
    <button onClick={() => setVisibility(!visible)}>
        Toggle
    </button>
)

const Toggle = ({ visible }) => visible ? <div>Hello</div> : null

export {
    ToggleButton: withState(ToggleButton),
    Toggle: withState(Toggle)
}

With render functions instead of contextToProps HoC:

import React from 'react'
import { StateConsumer } from './context'

export function ToggleButton() {
    return (
        <StateConsumer>
            {({ visible, setVisibility }) => (
                <button onClick={() => setVisibility(!visible)}>Toggle</button>
            )}
        </StateConsumer>
    )
}

export function Toggle() {
    return (
        <StateConsumer>
            {({ visible, setVisibility }) =>
                visible ? <div>Hello</div> : null
            }
        </StateConsumer>
    )
}

With redux connect

The same logic applies with a higher-order component like connect from the react-redux package:

import React from 'react'
import { propsToContext } from 'react-zap'
import { compose } from 'redux'
import { connect } from 'react-redux'
import ViewComponent from './ViewComponent'
import ViewChild from './ViewChild'

const { Provider, Consumer } = React.createContext()

// Set context for any component in `ViewComponent`
// All props received by `propsToContext` will be set to `Provider`,
// including what is returned by `mapStateToProps` and `mapDispatchToProps`
const ViewContainer = compose(
    connect(mapStateToProps, mapDispatchToProps),
    propsToContext(Provider)
)(ViewComponent)

// No we can consume our context in any descendant!
const ViewChild = () => <Consumer>{context => <div />}</Consumer>
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].