Package Exports
- zippy-store
- zippy-store/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (zippy-store) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
zippy-store
zippy-store is a lightweight, flexible, and type-safe global shared state management library for React, React Native, and JavaScript applications. It provides a simple API to manage global shared state, subscribe to state changes, and dispatch actions. With built-in support for selector, it ensures optimal performance by preventing unnecessary re-renders. Additionally, it includes seamless persistence, ensuring state is retained across sessions.
Features
- 🚀 Lightweight: Minimalistic API with zero dependencies.
- 🛠 Type-Safe: Built with TypeScript for better developer experience.
- 🎯 Selector: Extract specific parts of the state to avoid unnecessary re-renders.
- 🔄 Reactive: Automatically re-renders components when the state changes.
- 🧩 Modular: Create multiple stores for different parts of your application.
- 📦 Persistence: Built-in persistence support for JavaScript, React and React Native(AsyncStorage) apps.
- 🔗 Shared State: Share and sync state across multiple components seamlessly.
- 📊 Global Access: Access and update state globally from any component.
- 📤 State Synchronization: Ensure consistent data flow between different UI sections.
- ⚡️ Async Support: Handle asynchronous state updates effortlessly.
Installation
You can install zippy-store via npm:
npm install zippy-store
or
yarn add zippy-store
Usage
Creating a Store in React and React Native
You can create a store using the create
function and use it in components.
import { create } from "zippy-store";
const useCounterTimerStore = create("counterTimerStore", (set, get) => ({ //set for setting the state and get for getting the state
counter: 0,
timer: 60,
user: { name: "John Doe", age: 30 },
incrementCounter: () => set((state) => ({ counter: state.counter + 1 })), // return the new state in set function with callback
decrementTimer: () => {
const { timer } = get(); // get the current value of timer
return set({ timer: timer - 1 }); //can also pass object in set directly
},
}));
export default useCounterTimerStore;
Example 1: Using Full State
import React from "react";
import useCounterTimerStore from "./useCounterTimerStore";
const Example_1 = () => {
const { counter, timer, dispatch } = useCounterTimerStore();
return (
<div>
<h4>Example_1</h4>
<h2>Counter Value : {counter}</h2>
<h2>Timer Value: {timer}</h2>
<div>
<button onClick={dispatch.incrementCounter}>Increment Counter</button>
<button style={{ marginLeft: 10 }} onClick={dispatch.decrementTimer}>
Decrement Timer
</button>
</div>
</div>
);
};
export default Example_1;
Example 2: Using Selector to Optimize Re-renders
import React from "react";
import useCounterTimerStore from "./useCounterTimerStore";
const Example_2 = () => {
const { counter, user_name, dispatch } = useCounterTimerStore((state) => ({ counter: state.counter, user_name: state.user.name })); // using selector
return (
<div>
<h4>Example_2</h4>
<h2>User Name : {user_name}</h2>
<h2>Counter Value : {counter}</h2>
<div>
<button onClick={dispatch.incrementCounter}>Increment Counter</button>
<button style={{ marginLeft: 10 }} onClick={dispatch.decrementTimer}>
Decrement Timer
</button>
</div>
</div>
);
};
export default Example_2;
Example 3: Sharing State Between Components
Multiple components can share the same store and stay in sync with state updates.
import { create, store } from "zippy-store";
const useAuthStore = create("authStore", (set, get) => ({
isAuthenticated: false,
user: null,
login: (user) => set({ isAuthenticated: true, user }),
logout: () => set({ isAuthenticated: false, user: null }),
}));
import React from "react";
import useAuthStore from "./authStore"; // Assuming the store is in authStore.ts
const Header = () => {
const { isAuthenticated, user, dispatch } = useAuthStore();
return (
<header>
{isAuthenticated ? (
<div>
Welcome, {user?.name}!
<button onClick={dispatch.logout}>Logout</button>
</div>
) : (
<button onClick={() => dispatch.login({ name: "Test User", email: "test@example.com" })}>Login</button>
)}
</header>
);
};
const Profile = () => {
const { isAuthenticated, user } = useAuthStore();
return (
<div>
<h2>Profile</h2>
{isAuthenticated ? (
<p>Email: {user?.email}</p>
) : (
<p>Please login to view your profile.</p>
)}
</div>
);
};
Example 4: Async Support
zippy-store supports asynchronous state updates in actions.
import { create } from "zippy-store";
const useMoviesStore = create((set) => ({
data: {},
fetch: async () => {
const response = await someApiCall()
set({ data: respoonse.data })
},
}))
// or
const useMoviesStore = create((set) => ({
data: {},
fetch: () => {
set(async () => {
const response = await someApiCall()
return { data: respoonse.data }
})
},
}))
Example 4: Persistence Support
zippy-store supports persistence for React and JavaScript apps (React Native is not supported yet).
import { create } from "zippy-store";
const usePersistentStore = create("persistentStore", (set, get) => ({
theme: "light",
setTheme: (theme: string) => set(() => ({ theme })),
}), true); // Enable persistence with true as the third parameter
Creating a Store and using it directly in JavaScript, React and React Native apps
You can access the underlying store object for more advanced use cases and in non-React JavaScript environments(non React Components).
import { store } from 'zippy-store';
const { dispatch } = store.createStore('counterTimerStore', (set, get) => ({
counter: 0,
timer: 60,
user: { name: "John Doe", age: 30 },
incrementCounter: () => set((state) => ({ counter: state.counter + 1 })),
decrementTimer: () => set((state) => ({ timer: state.timer - 1 })),
}));
// Get the current state
const counterTimerState = store.getState('counterTimerStore');
// Subscribe to changes
const unsubscribe = store.subscribe('counterTimerStore', (newState) => {
console.log('Store updated:', newState);
});
// Update the state directly
dispatch.incrementCounter();
// or
const actions = store.getActions('counterTimerStore');
actions.incrementCounter();
// or
store.setState('counterTimerStore', (state) => ({ counter: state.counter + 1 }));
// Unsubscribe when done
unsubscribe();
API
create(storeKey: string, stateAndActionsFn: (set, get) => State & Partial<Actions>, persist?: boolean): Hook
Creates a new store for the given storeKey
.
Arguments:
storeKey
: Unique identifier for the store.stateAndActionsFn
: A function with the initial state and actions.set
allows updating the state.get
allows accessing the state.persist
: Boolean flag to enable persistence (default:false
).
Returns:
- A hook that can be used in React components to access the state and actions.
store
The global store object with the following methods:
store.createStore(key: string, stateAndActionsFn: (setState) => State & Actions, persist?: boolean): State
. Initializes the store with the givenkey
andstateAndActionsFn
and returns the dispatch object with actions.store.getActions(key: string): Actions
Returns the current actions of a givenstoreKey
.store.getState(key: string): State
Returns the current state of a givenstoreKey
.store.setState(key: string, newStateCb: (state) => Partial<State>)
Updates the state for a givenstoreKey
.store.subscribe(key: string, callback: (newState) => void): UnsubscribeFn
Subscribes to state changes of a givenstoreKey
and returns an unsubscribe function.
License
MIT
Powered by Harish Ponna @2025