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

v3.1.0

Published

React Context API based store

Downloads

7

Readme

React Localux 🐬 — context and hooks based store for React, TypeScript-friendly

npm version

React Localux (RL) is comfortable solution for separation store-related logic from react components. Unlike Redux main goal for RL is being home for compact local stores of smart components. Based on useReducer and new Context API.

For example, you might have screen-like component of some item with vast logic related to this screen and it is required to support several different stacked screens of such items. Implementing such feature with global Redux store result complicated code, but it turns out that using single local store for each screen produces quite straightforward solution.

React 16.8+ only, because it uses hooks (useReducer mainly). For React < 16.8 see v1.

Main features

  • Compact creation of store: just declare state, methods (combination of reducers and actions) and effects
  • Thunk-like actions support — effects
  • Default state support (handy for unit-testing)
  • Redux dev tools logging support
  • TypeScript first! Typings for all methods and effects for free.
  • API based on hooks
  • Lightweight: ~2.2 Kb non-gzipped and uglified

Example code (from example.tsx)

npm i react-localux constate
// example-store.ts
import { createUseStore } from "react-localux";

// example-store.ts
const pause = async (timeout: number): Promise<any> =>
  new Promise(resolve => setTimeout(resolve, timeout));

type State = {
  loading: boolean;
  data?: string;
  error?: boolean;
};

export const defaultState: State = {
  loading: false
};

export const useItemsStore = createUseStore(
  defaultState,
  {
    loading: () => () => ({
      loading: true
    }),
    loadSuccess: (state: State) => (data: string) => ({
      ...state,
      loading: false,
      data
    }),
    loadFailed: (state: State) => () => ({
      ...state,
      loading: false,
      error: true
    })
  },
  {
    loadItem: (_, methods) => async () => {
      methods.loading();
      // Pretend making API call which can fail
      await pause(1000);
      if (Math.random() > 0.5) {
        methods.loadSuccess("Hooray!😁");
      } else {
        methods.loadFailed();
      }
    }
  }
);

// example.tsx
function ItemScreen() {
  const { Provider } = useItemsStore;
  return (
    <Provider initialState={defaultState}>
      <Item />
    </Provider>
  );
}

function Item() {
  const { state, effects } = useItemsStore();

  return (
    <div>
      <h1>Item Screen</h1>
      {state.loading && <p>Loading...</p>}
      {state.error && <p>Error loading 😕</p>}
      {state.data && <p>Data loaded 🎆: {state.data}</p>}
      <button onClick={effects.loadItem}>Load item</button>
    </div>
  );
}

/**
 * If you need just slice of state and do not want re-renders
 * on other state parts change, you can do such optimization with useMemo
 **/
function ItemOptimized() {
    const { state } = useItemsStore();
    return useMemo(() => (
        <div>
          <h1>Item</h1>
          {state.data
            ? <p>{`Data loaded 🎆: ${state.data}`</p>
            : <p>Loading...</p>
          }
        </div>
    ), [state.data]);
}

Also see tests.

Similar solutions

react-waterfall:

  • No TypeScript support and due to API design decision for actions it is not possible to make types
  • No async actions support
  • Not very performant code on store creation

Alveron is really good lib with good documentation:

  • No TypeScript support and due to API design decision for actions it is not possible to make types (looks like it is possible now with TS 3.7)
  • No redux dev tools logging

Use methods

  • No async actions support built-in
  • No redux dev tools logging
  • API based on ambiguous immer (immer adds 4.3 Kb gzip). Immer adds performance penality on every action call, up to 15x on browsers without Proxy and 2x-3x on others.

Constate

— It is more "put any hook inside context" then complete store solution. — No default state support, which is usefull for unit-testing.

That's why this library has been born. 👭

Credits

Thanks to @viventus for helpfull discussions.

Thanks to Constate library for simple solution for placing hooks inside context.