@mxweb/react-provider
v1.0.0
Published
A lightweight, type-safe React state management library inspired by Redux Toolkit's createSlice. Quickly create reusable Context Providers without repetitive boilerplate code.
Downloads
2
Maintainers
Readme
@mxweb/react-provider
A lightweight, type-safe React state management library inspired by Redux Toolkit's createSlice, designed to quickly create reusable Context Providers without repetitive boilerplate code.
💡 Inspiration
This library takes inspiration from @reduxjs/toolkit's createSlice API, which provides a simple and intuitive way to define state and reducers. However, instead of using Redux, we wanted a solution that:
- ✨ Works with React Context - No additional Redux setup required
- 🚀 Factory-based Provider creation - Quickly create Providers for any part of your app
- 🔄 Zero boilerplate - No need to repeatedly write Provider, Context, and hooks
- 📦 Lightweight - Minimal dependencies, just React
- 🎯 Type-safe - Full TypeScript support with inferred types
The goal is to have a Provider factory that can be used anywhere in a project without repeating the Provider initialization process every time you need local state management.
📦 Installation
npm install @mxweb/react-provideryarn add @mxweb/react-providerpnpm add @mxweb/react-provider🚀 Quick Start
Basic Example
import { createProvider, PayloadAction } from '@mxweb/react-provider';
// 1. Create your provider with createProvider (similar to Redux Toolkit's createSlice)
const { Provider, useProvider } = createProvider({
name: 'Counter',
initialState: {
count: 0,
},
reducers: {
increment: (state) => {
state.count += 1;
},
decrement: (state) => {
state.count -= 1;
},
incrementByAmount: (state, action: PayloadAction<number>) => {
state.count += action.payload;
},
},
});
// 2. Wrap your component tree with the Provider
function App() {
return (
<Provider>
<Counter />
</Provider>
);
}
// 3. Use the hook to access state and actions
function Counter() {
const { count, increment, decrement, incrementByAmount } = useProvider();
return (
<div>
<h1>Count: {count}</h1>
<button onClick={increment}>+1</button>
<button onClick={decrement}>-1</button>
<button onClick={() => incrementByAmount(5)}>+5</button>
</div>
);
}📚 Features
1. Simple Provider Creation
No need to manually create Context, Provider, and hooks. Everything is generated automatically:
const { Provider, Consumer, useProvider } = createProvider({
name: 'MyProvider',
initialState: { /* ... */ },
reducers: { /* ... */ },
});2. Redux Toolkit-like API
Familiar API if you've used Redux Toolkit's createSlice:
createProvider({
name: 'Todo',
initialState: {
todos: [],
filter: 'all',
},
reducers: {
addTodo: (state, action: PayloadAction<string>) => {
state.todos.push({ id: Date.now(), text: action.payload, completed: false });
},
toggleTodo: (state, action: PayloadAction<number>) => {
const todo = state.todos.find(t => t.id === action.payload);
if (todo) todo.completed = !todo.completed;
},
setFilter: (state, action: PayloadAction<'all' | 'active' | 'completed'>) => {
state.filter = action.payload;
},
},
});3. Type-Safe
Full TypeScript support with automatic type inference:
const { useProvider } = createProvider({
name: 'User',
initialState: {
name: '',
age: 0,
},
reducers: {
setName: (state, action: PayloadAction<string>) => {
state.name = action.payload;
},
},
});
function Component() {
const { name, age, setName } = useProvider();
// ✅ name: string
// ✅ age: number
// ✅ setName: (payload: string) => void
}4. Initial State Override
Pass initial state values as props to the Provider:
<Provider count={10} max={100}>
<Counter />
</Provider>5. Middleware Support
Add middleware to intercept and modify actions:
const logger = (api) => (next) => (action) => {
console.log('Dispatching:', action);
const result = next(action);
console.log('Next state:', api.getState());
return result;
};
createProvider({
name: 'Counter',
initialState: { count: 0 },
reducers: { /* ... */ },
middleware: [logger],
});6. Consumer Component
Alternative render props pattern for accessing context:
<Consumer>
{({ count, increment }) => (
<div>
<p>{count}</p>
<button onClick={increment}>+</button>
</div>
)}
</Consumer>⚠️ Utility Functions
By default, this library uses basic implementations of cloneDeep and isEqual that work for simple use cases but have limitations (no circular reference handling, limited special object support, etc.).
For production apps with complex data structures, it's recommended to replace these with robust implementations like lodash before creating your providers:
import { UTIL_FUNCTIONS } from '@mxweb/react-provider/create-slice';
import cloneDeep from 'lodash.clonedeep';
import isEqual from 'lodash.isequal';
// Replace utility functions with lodash
UTIL_FUNCTIONS.cloneDeep = cloneDeep;
UTIL_FUNCTIONS.isEqual = isEqual;
// Now create your providers
const CounterProvider = createProvider({ /* ... */ });See the JSDoc comments in the source code for more details about the limitations of the default implementations.
🎯 Use Cases
This library is perfect for:
- 🎨 Component-level state - Modal dialogs, forms, wizards
- 🌳 Feature-level state - Shopping cart, user preferences, filters
- 📱 Multiple instances - Reusable components with independent state
- 🔧 Quick prototyping - Fast state management setup without Redux overhead
📖 API Reference
createProvider(options)
Creates a Provider with state management capabilities.
Parameters:
options.name(string) - Name of the provider (used for debugging)options.initialState(object | function) - Initial state or function that returns initial stateoptions.reducers(object) - Map of reducer functionsoptions.middleware?(array) - Optional middleware functions
Returns:
Provider- React component to wrap your app/component treeConsumer- React component for render props patternuseProvider- Hook to access state and actions
PayloadAction<Payload, Type, Meta, Err>
Type for actions with payload, metadata, and error information.
UTIL_FUNCTIONS
Object containing utility functions (cloneDeep, isEqual) that can be replaced with more robust implementations.
🤝 Comparison with Redux Toolkit
| Feature | @mxweb/react-provider | Redux Toolkit | |---------|----------------------|---------------| | Learning curve | ⭐⭐ Low | ⭐⭐⭐⭐ Medium-High | | Setup complexity | ⭐ Minimal | ⭐⭐⭐ Moderate | | Bundle size | 📦 Very small | 📦 Larger | | DevTools | ❌ No | ✅ Redux DevTools | | Middleware ecosystem | ⚠️ Basic | ✅ Rich ecosystem | | Time travel debugging | ❌ No | ✅ Yes | | Use case | Local/Feature state | Global app state |
📝 Examples
Check out the examples directory for more use cases:
- Counter example
- Todo list
- Form management
- Nested providers
📄 License
MIT
🙏 Credits
Inspired by @reduxjs/toolkit and the amazing work of the Redux team.
Made with ❤️ for developers who want simple, type-safe state management without the Redux ceremony.
