New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

zusdux

Package Overview
Dependencies
Maintainers
0
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

zusdux

The forbidden love child of Redux and Zustand

latest
Source
npmnpm
Version
0.1.3
Version published
Maintainers
0
Created
Source

Zusdux

The forbidden love child of Redux and Zustand ❤️‍🔥👶

What is Zusdux?

Zusdux is a type-safe state management library that combines the best of both worlds from Redux and Zustand. It has a Redux Toolkit-like API, but with Zustand's reduced boilerplate and simplicity. It also has a built-in support for React!

API

The API is pretty similar to what you'd find in Redux Toolkit's createSlice function, with a leaner signature, and without the need for providers or messing up with async thunks - similar to Zustand.

It has a single function, called createStore, which returns an object with getState, setState, subscribe, useStore, and actions properties.

Usage

First, you create a store with the createStore function. It takes an object with initialState and actions properties:

  • initialState - It's... well... the initial state of your store

  • actions - An object containing a list of actions that can be performed on the state. The actions can be either synchronous or asynchronous, they can take any number of arguments, while the first one is a set function that allows you to update the store's stat. The set function can accept either a new state object that will be shallowly merged with the current state, or a function that receives the current state and returns the new state. (See Zustand's documentation for more info)

// store.ts
import { createStore } from 'zusdux';

export const { actions, getState, setState, subscribe, useStore } = createStore(
  {
    initialState: {
      name: 'counter',
      count: 0,
      isLoading: false,
    },
    actions: {
      increment: (set) => {
        set((prev) => ({
          ...prev,
          count: prev.count + 1,
        }));
      },

      incrementBy: (set, by: number) => {
        set((prev) => ({
          ...prev,
          count: prev.count + by,
        }));
      },

      incrementAsync: async (set) => {
        set({ isLoading: true });

        await new Promise((resolve) => setTimeout(resolve, 100));

        set((prev) => ({
          ...prev,
          count: prev.count + 1,
          isLoading: false,
        }));
      },

      setName: (set, firstName: string, lastName: string) => {
        set({ name: firstName + ' ' + lastName });
      },
    },
  },
);

Each "store action" is then converted to a "user action" under the store object, which will update the store's state when called:

actions.increment();
actions.incrementBy(5);
await actions.incrementAsync();
actions.setName('new', 'name');

In addition, you can access the current store's state with the getState function, and update it with the setState function:

const currentState = getState(); // { name: 'counter', count: 0 }

setState((prev) => ({
  ...prev,
  count: 5,
}));

const updatedState = getState(); // { name: 'counter', count: 5 }

Similar to Redux, you can also subscribe to the store's state changes:

const unsubscribe = subscribe(() => {
  console.log('Current state:', getState());
});

unsubscribe();

And similar to Zustand, you can use the store within your React components:

// Counter.tsx
import { actions, useStore } from './store';

export const Counter = () => {
  const { name, count, isLoading } = useStore();

  return (
    <div>
      <h1>{name}</h1>
      <p>{isLoading ? 'Loading...' : 'Not loading'}</p>
      <p>Count: {count}</p>

      <button onClick={actions.increment}>Increment</button>

      <button onClick={() => actions.incrementBy(5)}>Increment by 5</button>

      <button onClick={actions.incrementAsync}>Increment async</button>

      <button onClick={() => actions.setName('new', 'name')}>Set name</button>
    </div>
  );
};

You can also provide a selector to the useStore function to select a specific part of the store, similar to what you'd do with Redux's useSelector

const count = useStore((state) => state.count);

This way, your component will only re-render when the selected part of the store changes.

As you might've noticed, we don't need a provider at all! 🥳

FAQs

Package last updated on 05 Aug 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts