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

@nexpy/react-easy-context-api

v2.0.1

Published

A simple way to create, consume and manipulate contexts from react context API.

Downloads

59

Readme

@nexpy/react-easy-context-api

npm size

Introduction

Many times when using the React Context API we create unnecessary repetitive and extensive code.

And, React Context and useContext is often used to avoid prop drilling, however it's known that there's a performance issue. When a context value is changed, all components that useContext will re-render.

To solve this issue, useContextSelector is proposed and later proposed Speculative Mode with context selector support. This library provides an easy way to build and use the Context API with these issues fixed.

This package is constructed above the use-context-selector.

Install

This package requires some peer dependencies, which you need to install by yourself.

yarn add @nexpy/react-easy-context-api scheduler

Notes for library authors:

Please do not forget to keep "peerDependencies" and note instructions to let users to install peer dependencies.

Technical memo

To make it work like original React context, it uses useReducer cheat mode intentionally. It also requires useContextUpdate to behave better in Concurrent Mode. (You don't need to use it in Legacy Mode.)

Usage

// cats-context.tsx
import { useState, FC } from 'react'

import { createContext } from '@nexpy/react-easy-context-api'

type MyContext = {
  pettedCats: number
  currentCats: number
}

const CatsContext = createContext<MyContext>({
  pettedCats: 0,
  currentCats: 0,
})

const CatsProvider: FC = ({ children }) => {
  const [pettedCats, setPettedCats] = useState(0)
  const [currentCats, setCurrentCats] = useState(0)

  // ... your context logic :)

  return (
    <CatsContext.Provider
      value={{
        pettedCats,
        currentCats,
      }}
    >
      {children}
    </CatsContext.Provider>
  )
}

export { CatsContext, CatsProvider }

// ... in your components
const CatsPetted = () => {
  const catsPettedNumber = CatsContext.useSelector(state => state.pettedCats)

  return <p>Petted cats: {catsPettedNumber}</p>
}

const CurrentCats = () => {
  const currentCatsNumber = CatsContext.useSelector(state => state.currentCats)

  return <p>Current cats: {currentCatsNumber}</p>
}

const App = () => (
  <CatsProvider>
    <CatsPetted />
    <CurrentCats />
  </CatsProvider>
)

API

createContext

This creates a special context.

Parameters

  • defaultValue: Value

Examples

import { createContext } from '@nexpy/react-easy-context-api'

type PersonContext = {
  firstName: string
  familyName: string
}

const PersonContext = createContext<PersonContext>({ firstName: '', familyName: '' })

createContext Returns:

useSelector

This hook returns context selected value by selector.

It will trigger re-render if only the selected value is referentially changed.

The selector should return referentially equal result for same input for better performance.

Parameters
  • selector: function (value: Value): Selected
Examples
const MyComponent = () => {
  const firstName = PersonContext.useSelector(state => state.firstName)

  return <p>{firstName}</p>
}

useContext

This hook returns the entire context value. Use this instead of React.useContext for consistent behavior.

Examples
const MyComponent = () => {
  const person = PersonContext.useContext()
  // ...
}

useContextUpdate

This hook returns an update function that accepts a thunk function.

Use this for a function that will change a value in Concurrent Mode. Otherwise, there's no need to use this hook.

Examples
const MyComponent = () => {
    const update = PersonContext.useContextUpdate()

    update(() => setState(...));
    // ...
}

Provider

The provider you need to use to apply the context.


Exotic Returns:

You probably won't need the following features. Use only if you know what you are doing.

Context

The special context created by createContext hook. This context should not be consumed by the ro react useContext API, but by useSpecialContext bellow.

useSpecialContext

This Hook is used to manually consume the same special context Context created by createContext function. This is not necessary as there is a level of abstraction on top of that and this hook should only be used with contexts created by the library. This utility is only available so there are no limitations on the use of this library.

useBridgeValue

This hook return a value for BridgeProvider.

BridgeProvider

This is a Provider component for bridging multiple react roots.

Parameters
  • $0 Object
    • $0.context
    • $0.value
    • $0.children
Examples
import { createContext } from '@nexpy/react-easy-context-api'

type PersonContext = {
  firstName: string
  familyName: string
}

const { Context, useBridgeValue, BridgeProvider } = createContext<PersonContext>({
  firstName: '',
  familyName: '',
})

const App = () => {
  const valueToBridge = useBridgeValue()

  return (
    <>
      <BridgeProvider context={Context} value={valueToBridge}>
        {children}
      </BridgeProvider>
    </>
  )
}

Limitations

  • In order to stop propagation, children of a context provider has to be either created outside of the provider or memoized with React.memo.
  • Provider trigger re-renders only if the context value is referentially changed.
  • Neither context consumers or class components are supported.
  • The stale props issue can't be solved in userland.
  • Tearing is only avoided if all consumers get data using useSelector. If you use both props and selector to pass the same data, they may provide inconsistence data for a brief moment.

Examples

See this example file.