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.

Jan 23, 2025 - 10:04
 0
Reactive State Management Without Libraries

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

  1. State changes trigger updates
  2. Subscribers automatically notified
  3. No complex stream processing
  4. 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?

like

dislike

love

funny

angry

sad

wow