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 🙏

© 2026 – Pkg Stats / Ryan Hefner

use-context-member

v1.0.3

Published

use context's member like using useState

Readme

Introduction

use-context-member provided useMember hook,to use React Context more easily and reduce component render times.
- Official useContext: const { user } = useContext(UserContext)
- Our useMember: const [user, setUser] = useMember(UserContext, 'user')
The 2 examples are both to select user value from UserContext. Our useMember hook also returned a setter, you can directly use it to modify user. What's more useMember will reduce component's render times. Only if user is changed, the component will re-render. Well for useContext, the component will re-render when any member of UserContext changed.

Install

npm i -D use-context-member

API

createContext

use-context-member Provided createContext, same usage with React.createContext.You can not use React.createContext directly.

import { createContext } from 'use-context-member';

const UserContext = createContext();

const User = () => {
  const user = {name: {firstname: 'Harry', lastname: ''}, id: '001', email: ['[email protected]']};
  return (
    <UserContext.Provider value={user}>
      <SomeOtherComponent />
    </UserContext.Provider>
  )
}

inside context, we maintained it's state, if you need to listen the change of it, you can use onChange property.

const handleChange = useCallback(data => {
  // do something
}, [])
return (
  <UserContext.Provider value={user} onChange={handleChange}>
    <SomeInnerComponents />
  </UserContext.Provider>
)

useMember

import { useMember } from 'use-context-member';

const [name, setName] = useMember(UserContext, 'name')
[name, setName] are similar with useState. function type param are supported for setName too.
The first param is the UserContext you created.
The second param is an expression, used to select member from context. If you left it as undefined, then it means to select the whole context. expression rules are simple.
- use . to select member from object, the first . can be omitted: 'name.firstname', You can also use [] to select: '[name][firstname]', Sure you can mix the both: 'name[firstname]'
- use [] to select member from array: 'email[0]'. negative number are supported too: 'email[-1]', same meaning as param for Array.slice. You can even make a simple finder: for example when context is [{id: '001'}, {id: '002'}], use '[id==001]' to select the first element(only == is supported at here).
When the selected member is an element of an array, a deleter are provided as the third part of return value: const [email, setEmail, deleteEmail] = useMember(UserContext, 'email[0]'), execute deleteEmail() will delete this email form the email array.
the returned setter and deleter are both stable, so you can safely append them to some hooks' dependencies, e.g., useCallback, useEffect.

useOperations

import { useOperations } from 'use-context-member';

const [setEmail, deleteEmail] = useOperations(UserContext, 'email[0]`)
Same with useMember, except that this hook will not get the select member itself.

useSelector

import { useSelector } from 'use-context-member';

const email = useSelector(UserContext, s => s.email.find(email => email.endsWith('mail.com')))
Like Redux, use a function to select member. useMember can handle most scenario in your application. However expression is not enough for some complex cases, and then please use useSelector instead. On the other hand, useSelector don't provide a setter, you need to use useOperations to get one. I suggest you use immer to deal with complex update logic.

No need to care NPE in hooks

useMember, useOperations and useSelector have already catch the exceptions, and return undefined as the selected member's value when exception occurred. That's because Context.Provider is just a component, we should allow to leave it's value as null in initialization, and then update it in side effects.

One Example

import React, { useEffect, useState, useRef, useCallback } from 'react';
import { createContext, useMember } from 'use-context-member'

const BookContext = createContext();

const Book = ({ id }) => {
  const [book, setBook, deleteBook] = useMember(BookContext, `books[id==${id}]`);
  if (!book) { // handle stale props issue(that is, if you used props in useMember's expression, the returned member can be undefined.)
    return <></>;
  }
  const { name, count } = book;
  return (
    <div>
      <div>{name}</div>
      <div>Count: {count}</div>
      <button onClick={() => setBook({ ...book, count: book.count + 1 })}>Add Count</button>
      <button onClick={() => deleteBook()}>Delete</button>
    </div >
  )
}

const BookList = () => {
  const [books = [], setBooks] = useMember(BookContext, 'books');
  const [title] = useMember(BookContext, 'title');
  const maxId = useRef(5);

  const handleAddBook = useCallback(() => {
    maxId.current += 1;
    setBooks(prev => [...prev, { name: 'Book' + maxId.current, count: 1, id: maxId.current }]);
  }, [setBooks]); // `setBooks` is stable.

  return (
    <div>
      <div>{title}</div>
      {
        books.map(book => <Book key={book.id} id={book.id} />)
      }
      <button onClick={handleAddBook}>Add Book</button>
    </div>
  )
}

export const TestPage = () => {
  const [bookContext, setBookContext] = useState();

  useEffect(() => { // set context value in side effect is ok, for useMember just return undefined when target member can't be found.
    const mockBooks = [];
    for (var i = 0; i < 1; ++i) {
      mockBooks.push({ id: i, name: 'Book' + i, count: 1 });
    }
    setBookContext({
      books: mockBooks,
      title: 'Book List',
    })
  }, [])

  return (
    <BookContext.Provider value={bookContext}>
      <BookList />
    </BookContext.Provider>
  )
}

License

MIT