0.1.0 • Published 4 months ago

@domeadev/react-store-context v0.1.0

Weekly downloads
-
License
MIT
Repository
github
Last release
4 months ago

React Store Context

A simple and lightweight store context for React built on top of Zustand.

Installation

npm

npm install @domeadev/react-store-context

yarn

yarn add @domeadev/react-store-context

pnpm

pnpm add @domeadev/react-store-context

Features

  • 🪶 Lightweight wrapper around Zustand
  • 🧩 Context-based state sharing
  • 🔄 Component subscription with minimal re-renders
  • 🎯 Type-safe selectors
  • 🌳 Tree-shakeable exports

Usage

Basic Example

import {
  createDefaultStore,
  createStoreContext,
} from "@domeadev/react-store-context";
import React from "react";

// Define todo type
interface Todo {
  id: string;
  text: string;
  completed: boolean;
}

// Create a store creator function
const createTodosStore = () =>
  createDefaultStore(
    // initial state
    { todos: [] as Todo[] },
    (set) => ({
      addTodo: (text: string) =>
        set((state) => ({
          todos: [
            ...state.todos,
            { id: Math.random().toString(36).slice(2, 9), text, completed: false },
          ],
        })),
      toggleTodo: (id: string) =>
        set((state) => ({
          todos: state.todos.map((todo) =>
            todo.id === id ? { ...todo, completed: !todo.completed } : todo
          ),
        })),
      removeTodo: (id: string) =>
        set((state) => ({
          todos: state.todos.filter((todo) => todo.id !== id),
        })),
    })
  );

// Create the store context
const { StoreProvider, useStore, Subscribe, createStoreSelector } =
  createStoreContext(createTodosStore);

// Use selectors for type safety
const selectTodos = createStoreSelector((state) => state.todos);
const selectActions = createStoreSelector((state) => ({
  addTodo: state.addTodo,
  toggleTodo: state.toggleTodo,
  removeTodo: state.removeTodo,
}));

// TodoList component
const TodoList = () => {
  const todos = useStore(selectTodos);
  const { toggleTodo, removeTodo } = useStore(selectActions);

  return (
    <ul>
      {todos.map((todo) => (
        <li key={todo.id} style={{ textDecoration: todo.completed ? "line-through" : "none" }}>
          <input
            type="checkbox"
            checked={todo.completed}
            onChange={() => toggleTodo(todo.id)}
          />
          {todo.text}
          <button onClick={() => removeTodo(todo.id)}>Delete</button>
        </li>
      ))}
    </ul>
  );
};

// App component
const App = () => {
  return (
    <StoreProvider>
      <TodoList />
      {/* Other components that need access to the todos state */}
    </StoreProvider>
  );
};

Using the Subscribe Component

You can use the Subscribe component for declarative subscriptions:

const TodoCounter = () => {
  return (
    <Subscribe selector={selectTodos}>
      {(todos) => (
        <div>
          Total: {todos.length} | Completed: {todos.filter(todo => todo.completed).length}
        </div>
      )}
    </Subscribe>
  );
};

Passing Initial Props

You can pass initial props to your store:

interface TodoStoreProps {
  initialTodos?: Todo[];
}

const { StoreProvider } = createStoreContext((props?: TodoStoreProps) =>
  createDefaultStore(
    { todos: props?.initialTodos || [] },
    (set) => ({
      addTodo: (text: string) =>
        set((state) => ({
          todos: [
            ...state.todos,
            { id: Math.random().toString(36).slice(2, 9), text, completed: false },
          ],
        })),
      toggleTodo: (id: string) =>
        set((state) => ({
          todos: state.todos.map((todo) =>
            todo.id === id ? { ...todo, completed: !todo.completed } : todo
          ),
        })),
      removeTodo: (id: string) =>
        set((state) => ({
          todos: state.todos.filter((todo) => todo.id !== id),
        })),
    })
  )
);

// Usage
<StoreProvider initialTodos={[
  { id: '1', text: 'Learn React', completed: true },
  { id: '2', text: 'Learn TypeScript', completed: false },
]}>
  <TodoList />
</StoreProvider>;

API Reference

createStoreContext(storeCreator)

Creates a React context for your store.

Parameters:

  • storeCreator: A function that creates a store instance

Returns:

  • StoreContext: The React context object
  • StoreProvider: A provider component for the store
  • useStore: A hook to access the store state
  • createStoreSelector: A utility to create typed selectors
  • Subscribe: A component for declarative subscriptions

createDefaultStore(initialState, actionsCreator)

Creates a default store with initial state and actions.

Parameters:

  • initialState: The initial state object
  • actionsCreator: A function that returns actions using Zustand's set function

License

MIT © domeafavour

0.1.0

4 months ago

0.0.1

5 months ago