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-reverse-context

v0.1.0

Published

React's Context API but with Provider inside Consumer

Downloads

4

Readme

react-reverse-context

React's Context API is great. It allows us to pass an object down the react tree to any level that requests it. But do you wish sometimes to pass something up? Go in the reverse direction? Reverse Context can help.

Demo, ideas, and example usage

A simple demo is available here.

You might like to use Reverse Context for the following:

  • Sometimes the content of a sidebar (defined near the root element of an app) should depend on deeply nested child components.
  • As a substitute to passing down callbacks through props several levels of the tree.
  • Display a modal higher up the tree. (Although don't forget about using react-modal for this.)
  • Display a component in a completely different location to where it would appear if rendered normally.

Here's a very simple example of usage:

import { createReverseContext } from 'react-reverse-context'

const { Consumer, Provider } = createReverseContext()
export default () => (
    <Consumer>
        {value => (
            <div className="container">
                <div className="beside">
                    <Provider value="foo" />
                </div>
                <div className="content">{value}</div>
            </div>
        )}
    </Consumer>
)

which will render:

<div className="container">
    <div className="beside" />
    <div className="content">foo</div>
</div>

That is, even though the value foo is given inside the beside div, it appears outside/above it, in the content div.

Install

$ npm install --save react-reverse-context
# or
$ yarn add react-reverse-context

API

The API is exactly the same as the React Context API, except for the following differences:

  • The Consumer must be the parent of the Provider
  • There can be multiple Providers. They all send their values to the consumer in the order they are instanciated, so that means the last created Provider has the final value.

The key differences from the React docs are italicized below.

const { Provider, Consumer } = createReverseContext([defaultValue])

Creates a { Provider, Consumer } pair. When React renders a context Consumer, it will read the current context value from a Provider below it in the tree.

The defaultValue argument is used by a Consumer when it does not have a matching Provider below it in the tree, and on the initial render.

<Provider value={/* some value */}>

Accepts a value prop to be passed to the Consumer that are parents of this Provider. One Consumer can be connected to many Providers, and the last rendered Provider is the final consumed value. A Provider cannot have children.

<Consumer>{value => /* render something based on the context value */}</Consumer>

A React component that subscribes to context changes. Requires a function as a child. The function receives the current context value and returns a React node. The value argument passed to the function will be equal to the value prop of the last rendered Provider for this context below in the tree. If there is no Provider for this context below, the value argument will be equal to the defaultValue that was passed to createReverseContext().

Minor notes and tips

  • Depending on how you are using it, it is a very good idea to define a default value. The default value is always used before the providers send their values. This may be only milliseconds in some cases, but it still might break your app.
  • The Provider component does not render anything, nor uses children.
  • It is important to not enter a render loop. If your app enters a loop, check that all your render functions between the Consumer and Providers are simple functions of props and state. They should not be creating new react classes in the render function. Pay specific attention to the Functional Components, as it is easy to forget these and be creating and consuming new classes every time you render. Essentially, you need to make sure that when the Consumer receives the value it doesn't create a new Provider (which will send another value causing a loop). If you are still having problems, create an issue with a simple example of your problem.

Alternatives

This was made as a simpler alternative to the following, but you might like the more complete alternatives:

  • Official React portals - Render an element to a DOM node. Can render outside the root component but restricted to DOM nodes.
  • react-portal - A component for the above React portal API
  • react-slot-fill - Define a slot by a name and in another place you can define something to fill it. More powerful but more boilerplate and works on magic strings (or you can use Symbols).

License

MIT © Eedrah