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-superstore

v0.1.4

Published

Simple hook to manage global state in react

Downloads

41

Readme

React Superstore - A React Global State Hook

Simple hook for adding and managing global state in your react app. You can get and set values from anywhere in your app.

Installation

Latest requirements are React >= 18.0.0

npm install react-superstore

For older versions minimum requirements are React versions with the useEffect hook 16.8.0 - 17.0.2

npm install [email protected]

Usage

Create a store anywhere in your app and pass in an initial state as the first argument in your createStore function and an optional reducer as the second argument. You can create as many instances as you like. The createStore function returns 3 functions in an array [useStore, setStore, getStore]:

  1. useStore() which is to be used in your react component to use the store value. This is the function that will re-render your component when the store value changes This is a react hook and will need to be used in a react function component.

  2. setStore() which sets the store and can be used anywhere in your app inside or outside of a react compoonent. This can be used just like reacts setState. You can set the store directly like setStore(newStore) or pass a function that has the current store value as an argument and return your new store value to set it setStore(currentStore => currentStore + 1). If you pass in a reducer then the reducer will be used to set the store instead.

  3. getStore() which can be used anywhere in your app inside or outside of a react component to get the store value. You can use this inside a react component but it won't cause a re render of the component.

Simple Pattern Usage

Lets show some examples. We will make a simple counter.

The function returns an array of the 3 functions so you can destructure them and call them whatever you like. In this case we will extract the useStore, setStore and getStore functions and call them useCount, setCount and getCount.

Create a store somewhere in your app.

import createStore from 'react-superstore'

export const [useCount, setCount, getCount] = createStore(0)

Consume in your react component.

import { useCount, setCount } from 'location of your store'

function Counter() {
  const count = useCount()

  const handleClick = () => setCount(count + 1)

  return (
    <>
      <p>Count: {count}</p>
      <button onClick={handleClick}>+</button>
    </>
  )
}

Reducer Pattern Usage

You can pass a reducer as the second argument in your createStore function and then the setStore function will use the reducer to set the store.

import createStore from 'react-superstore'

function reducer(store, action) {
  switch (action.type) {
    case 'INCREASE':
      return store + 1
    default:
      return store
  }
}

export const [useCount, setCount] = createStore(0, reducer)

Consume in your component and use just like the simple example above but now you will use the reducer when you call your dispatch function.

import { useCount, setCount } from 'location of your store'

function Counter() {
  const count = useCount()

  const handleClick = () => setCount({ type: 'INCREASE' })

  return (
    <>
      <p>Count: {count}</p>
      <button onClick={handleClick}>+</button>
    </>
  )
}

Maximize Performance And Avoid Unwanted Re-Renders

By default the useStore() hook returns then entire store. You can pass in a selector function to return only the values that you want to use in your component. This will trigger a shallow compare when setting the store that compares the previous store to the new store. The selector function should include one argument that will be the current store value and then you should return the values that you want to use. Eg. const foo = useStore(store => store.foo). Consider the following example.

import createStore from 'react-superstore'

const intialStore = {
  foo: 'foo',
  bar: 'bar',
  baz: 'baz',
}

export const [useStore] = createStore(initialStore)

In your react component you can do the following and your component will only re-render if the foo value changes. If the bar or baz values change your component will not re-render.

import { useStore } from 'location of your store'

function ReactComponent() {
  const foo = useStore((store) => store.foo)

  return <p>Foo: {foo}</p>
}

Or you can return an object and the dispatch function will shallow compare values for equality. In the following you can map the foo and bar values to your component and then you can avoid re-renders if the baz value changes.

import { useStore } from 'location of your store'

function ReactComponent() {
  const { foo, bar } = useStore((store) => {
    return {
      foo: store.foo,
      bar: store.bar,
    }
  })

  return (
    <p>
      Foo: {foo} - Bar: {bar}
    </p>
  )
}

Usage With Typescript

Stores are fully typescript compatible. When you create a store just pass in the store type to get your types inferred while using the store.

Simple Example Typescript

import createStore from 'react-superstore'

export const [useCount, setCount, getCount] = createStore<number>(0)

Complex Store Example Typescript

import createStore from 'react-superstore'

type Store = {
  foo: string
  bar: string
  baz: string
}

export const [useStore, setStore, getStore] = createStore<Store>({
  foo: 'foo',
  bar: 'bar',
  baz: 'baz',
})

Reducer Store Example Typescript

Create a store type and an action type. Pass both in when creating the store. createStore<Store, Action>(...your store).

import createStore from 'react-superstore'

type Store = {
  foo: string
  bar: string
  baz: string
}

type Action = {
  type: string
  payload: any
}

function reducer(store: Store, action: Action): Store {
  switch (action.type) {
    case 'SET_BAZ':
      return {
        ...store,
        baz: action.payload,
      }
    default:
      return store
  }
}

export const [useStore, setStore, getStore] = createStore<Store, Action>(
  {
    foo: 'foo',
    bar: 'bar',
    baz: 'baz',
  },
  reducer
)

License

Distributed under the MIT License. See LICENSE for more information.