Reactive State Management Without Libraries
Simple, Powerful State Handling export class State { private data: Map = new Map(); private subscribers: Map void)[]> = new Map(); set(name: keyof IState, value: IState[keyof IState]): void { this.data.set(name, value); this.publish(`change:${String(name)}`, value); } get(name: keyof IState): any | undefined { return this.data.get(name); } has(name: keyof IState): boolean { return this.data.has(name); } clear(): void { this.data.clear(); this.publish('clear'); } publish(name: string, ...args: any[]): void { this.subscribers.get(name)?.forEach(fn => fn(...args)); } subscribe(name: string, fn: (...args: any[]) => void): void { this.subscribers.has(name) ? this.subscribers.get(name)!.push(fn) : this.subscribers.set(name, [fn]); } unsubscribe(name: string, fn: (...args: any[]) => void): void { if (this.subscribers.has(name)) { const idx = this.subscribers.get(name)!.indexOf(fn); if (idx > -1) this.subscribers.get(name)!.splice(idx, 1); } } unsubscribeAll(name: string): void { this.subscribers.delete(name); } } Data Binding: The Real Reactivity React Integration Example function UserProfile() { const state = new State(); const [userData, setUserData] = useState({ name: state.get('name') || '', age: state.get('age') || 0 }); // Automatic reactivity through state changes state.subscribe('change:name', (newName) => { setUserData(prev => ({ ...prev, name: newName })); }); return ( state.set('name', target.value)} /> ); } Why This Beats Reactive Libraries Zero external dependencies Minimal bundle size Native JavaScript performance Simple, intuitive API Built-in change tracking Key Reactive Principles State changes trigger updates Subscribers automatically notified No complex stream processing Direct, predictable data flow Conclusion Reactivity isn't about libraries. It's about understanding how data flows and changes. This implementation proves that powerful state management is native to JavaScript.
Simple, Powerful State Handling
export class State<IState = Record<string, unknown>> {
private data: Map<keyof IState, IState[keyof IState]> = new Map();
private subscribers: Map<string, ((...args: any[]) => void)[]> = new Map();
set(name: keyof IState, value: IState[keyof IState]): void {
this.data.set(name, value);
this.publish(`change:${String(name)}`, value);
}
get(name: keyof IState): any | undefined {
return this.data.get(name);
}
has(name: keyof IState): boolean {
return this.data.has(name);
}
clear(): void {
this.data.clear();
this.publish('clear');
}
publish(name: string, ...args: any[]): void {
this.subscribers.get(name)?.forEach(fn => fn(...args));
}
subscribe(name: string, fn: (...args: any[]) => void): void {
this.subscribers.has(name)
? this.subscribers.get(name)!.push(fn)
: this.subscribers.set(name, [fn]);
}
unsubscribe(name: string, fn: (...args: any[]) => void): void {
if (this.subscribers.has(name)) {
const idx = this.subscribers.get(name)!.indexOf(fn);
if (idx > -1) this.subscribers.get(name)!.splice(idx, 1);
}
}
unsubscribeAll(name: string): void {
this.subscribers.delete(name);
}
}
Data Binding: The Real Reactivity
React Integration Example
function UserProfile() {
const state = new State<{
name: string;
age: number;
}>();
const [userData, setUserData] = useState({
name: state.get('name') || '',
age: state.get('age') || 0
});
// Automatic reactivity through state changes
state.subscribe('change:name', (newName) => {
setUserData(prev => ({ ...prev, name: newName }));
});
return (
<div>
<input
value={userData.name}
onChange={({target}) => state.set('name', target.value)}
/>
</div>
);
}
Why This Beats Reactive Libraries
- Zero external dependencies
- Minimal bundle size
- Native JavaScript performance
- Simple, intuitive API
- Built-in change tracking
Key Reactive Principles
- State changes trigger updates
- Subscribers automatically notified
- No complex stream processing
- Direct, predictable data flow
Conclusion
Reactivity isn't about libraries. It's about understanding how data flows and changes. This implementation proves that powerful state management is native to JavaScript.
What's Your Reaction?