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

reasy-state

v1.0.39

Published

reasy-state - A state management library for React

Downloads

917

Readme

Build Status Build Size Version Downloads

Reast Easy State

Reast Easy State is simple state management for React

Reasy-state allows you to easily work with your state without creating selectors or worrying about re-renders, by having each object element have its own hook for getting the value, get/set functions and mutators

Installation

To install the latest stable version, run the following command:

npm install reasy-state

Usage example

Create a state

Create state and export necessary functions

The function names will be generated automatically, depending on your object. ( get*, set*, use* and reset*storageName*)

// store.ts

import { createState } from "reasy-state";

const userStore = {
    id: 1,
    name: "User Name",
    settings: {
        notification: {
            message: true,
        },
    },
};

export const {
    getUserStoreId,
    useUserStoreName,
    useUserStoreSettingsNotificationMessage,
    setUserStoreSettingsNotificationMessage,
    resetUserStore,
} = createState({ userStore });

Use exported functions in your components

// user.tsx

import { getUserStoreId, useUserStoreName } from "./store";

const UserComponent = () => {
    const userName = useUserStoreName();
    return (
        <div>
            <p onClick={() => console.log("User ID:", getUserStoreId())}>
                {userName}
            </p>
            <button onClick={resetUserStore}>Reset store</button>
        </div>
    );
};
// setting.tsx

import {
    setUserStoreSettingsNotificationMessage,
    useUserStoreSettingsNotificationMessage,
} from "./store";

const SettingsNotificationComponent = () => {
    const checked = useUserStoreSettingsNotificationMessage();

    const onChange = () =>
        setUserStoreSettingsNotificationMessage((prev) => !prev);

    return (
        <>
            <span>Notification</span>
            <input type="checkbox" checked={checked} onChange={onChange} />
        </>
    );
};

Mutators

You can use 'mutators' to export functions. You can also use closures and async functions inside mutators. Use a "set" or "patch" function that takes a new value, or a function that takes the old value as a parameter and returns a new value, to change the state of the current object in the state. "set" / "patch" will return you the new state of the object. Use a "get" function for async mutators, for get previous object value, or use second function argument

mutators: {
  [functionName]: ({set, patch, get}, previousValue) => ...
}
// store.ts
import { createState, CreateState } from "reasy-state";

type UserStore = {
    id: number,
    data: {
        rating: number,
        other: number,
        mutators: {
            clear: void, // clear function
            inc: void, // increment function
            dec: Promise<boolean>, // decrement async function
            add: (value: number) => void, // add value function with arg
            remove: (value: number) => Promise<string>, // remove value async function with arg
        },
    },
    mutators: {
        ratingInc: void,
        changeId: void,
    },
};

const userStore: CreateState<UserStore> = {
    id: 1,
    data: {
        rating: 0,
        other: 1,
        mutators: {
            clear: ({ set }) => set({ rating: 0, other: 0 }),
            inc: ({ patch }, { rating }) => patch({ rating: rating + 1 }),
            /* OR
      inc: ({ patch, get }) => patch({ rating: get().rating + 1 }),
      */
            dec: async ({ patch, get }) => {
                await new Promise((f) => setTimeout(f, 1000));
                patch({ rating: get().rating - 1 });
                return true;
            },
            /* OR
      dec: async ({ patch }) => {
        await new Promise((f) => setTimeout(f, 1000));
        patch(({ rating }) => ({ rating: rating - 1 }));
        return true;
      },
      */
            add:
                ({ patch }, { rating }) =>
                (value) =>
                    patch({ rating: rating + value }),
            remove:
                ({ patch, get }) =>
                async (value) => {
                    await new Promise((f) => setTimeout(f, 1000));
                    patch({ rating: get().rating - value });
                    return "success";
                },
        },
    },
    mutators: {
        // hooks useUserStoreData, useUserStoreDataRating, useUserStoreDataOther will not be called
        changeId: ({ patch }) => patch({ id: 2 }),

        // some data.mutators.inc, hooks useUserStoreId and useUserStoreDataOther will not be called
        ratingInc: ({ patch }, { data: { rating } }) =>
            patch({ data: { rating: rating + 1 } }),
    },
};

export const {
    userStoreDataClear,
    userStoreDataInc,
    userStoreDataDec,
    userStoreDataAdd,
    userStoreDataRemove,
    useUserStoreDataRating,
} = createState({ userStore });
// rating.tsx
import {
    useUserStoreDataRating,
    userStoreDataAdd,
    userStoreDataClear,
    userStoreDataInc,
    userStoreDataDec,
    userStoreDataRemove,
} from "./store.ts";

export const UserRating = () => {
    const rating = useUserStoreDataRating();

    return (
        <>
            <div>
                <button
                    onClick={async () => {
                        const response = await userStoreDataRemove(5);
                        console.log(response); // "success"
                        return response;
                    }}
                >
                    -5
                </button>
                <button
                    onClick={async () => {
                        const response = await userStoreDataDec();
                        console.log(response); // true
                        return response;
                    }}
                >
                    -
                </button>
                <span>{rating}</span>
                <button onClick={userStoreDataInc}>+</button>
                <button onClick={() => userStoreDataAdd(5)}>+5</button>
            </div>
            <button onClick={userStoreDataClear}>Clear</button>
        </>
    );
};

Also, you can avoid specifying mutator types explicitly by using currying

// store.ts
import { createState } from 'reasy-state';

type UserStore = {
  userStore: {
    id: number;
    data: {
      rating: number;
    };
  };
};

export const {
  userStoreDataClear, // return new rating value
  useUserStoreDataRating,
} = createState<UserStore>()({
  userStore: {
    id: 1,
    data: {
      rating: 0,
      mutators: {
        clear: ({ set }) => set({ rating: 0 }).rating,
      },
    },
  },
});

Undefined params

You can use functions for undefined parameters using the $ sign

// store.ts
type UserStore = {
    id: number,
    data?: {
        rating: number,
    },
};
const userStore: CreateState<UserStore> = {
    id: 1,
};

export const { useUserStore$data$rating } = createState({ userStore });

Arrays

You can use arrays parameters functions using the $ sign

For array element "set", "get" and "use" functions, you can use a filter to specify which elements you need to get or change

get`[...functionName]`(filterFunction?);
use`[...functionName]`(filterFunction?);
set`[...functionName]`(filterFunction, newValue);
// store.ts

type UserStore = {
    id: number,
    subscribers: {
        id: number,
        rating: number,
    }[],
};

const userStore: CreateState<UserStore> = {
    id: 1,
    subscribers: [
        { id: 2, rating: 10 },
        { id: 3, rating: 12 },
    ],
};

export const {
    useUserStoreSubscribers$rating,
    setUserStoreSubscribers$rating,
} = createState({ userStore });
export const Ratings = () => {
    const ratings = useUserStoreSubscribers$rating(({ rating }) => rating);

    const add = () =>
        setUserStoreSubscribers$rating(
            ({ id }) => id === 2,
            (prev) => prev + 1,
        );

    const clear = () => setUserStoreSubscribers$rating(() => true, 0);

    return (
        <div>
            <p>Positive ratings = {ratings.join(",")}</p>
            <button onClick={add}>Add rating for id 2</button>
            <button onClick={clear}>Clear rating for all</button>
        </div>
    );
};

Storage

You can save the state in the store( localStorage (default), sessionStorage ) To do this, specify a unique key and configure saving if necessary

    const store = { value: "value" }
    const { ... } = createState({ store }, { key: "storage_state_1", storage: true });

If necessary, you can mutate the data on read and write like this (This can be useful when using momentjs for example):

    const store = { id: 1, date: moment() };

    const { ... } = createState(
        { store },
        {
            key: "session_storage_date_1",
            storage: {
                type: sessionStorage,
                mutators: {
                    store: {
                        date: (mutate) =>
                            mutate({
                                put: (prev) => prev.toISOString(),
                                get: (prev) => moment(prev),
                            }),
                    },
                },
            },
        },
    );