Newborn Programming Monsters

    @cimacmillan/refunc
    TypeScript icon, indicating that this package has built-in type declarations

    1.0.3 • Public • Published

    Refunc

    Redux-like state container with actions as functions

    By Callum Macmillan

    Quick start

    Installing

    npm install @cimacmillan/refunc
    

    Usage

    Refunc takes actions as functions, with payload as parameters

    const emptyActions = {
        increment: () => {},
        addX: (x: number) => {}
    }
    

    Reducers are defined as their initial state and functions for transforming state based on actions

    const reducer = {
        state: {
            count: 0
        },
        actions: {
            increment: (state: State) => ({...state, count: state.count + 1}),
            addX: (state: State, x: number) => ({...state, count: state.count + x}),
        }
    }
    

    The store is created by passing a reducer definition, and the empty actions

    const store = new Store(
        reducer,
        emptyActions
    );
    

    The store is updated by calling actions

    store.getActions().increment();
    store.getActions().addX(10);
    // store.getState() = { count: 11 }
    

    The store can notify listeners of changes to the state

    store.addChangeListener(() => {
        console.log(`new state is ${store.getState()}`)
    });
    

    The stores actions can be subscribed to

    store.subscribe({
        increment: () => {
            console.log("increment was called");
        },
        addX: (x: number) => {
            console.log(`addX was called with ${x}`);
        }
    })
    

    Multiple reducers can be combined with combineReducers

    const countReducer: Reducer<CountState, Actions> = {
        state: 0,
        actions: {
            increment: (state: CountState) => (state + 1),
            addX: (state: CountState, x: number) => (state + x),
        }
    }
    
    const numberOfCallsReducer: Reducer<CallRecordState, Actions> = {
        state: 0,
        actions: {
            increment: (state: CountState) => (state + 1),
            addX: (state: CountState, x: number) => (state + 1),
        }
    }
    
    const store = new Store(
        combineReducers({
            count: countReducer,
            numberOfCalls: numberOfCallsReducer
        }),
        emptyActions
    );
    
    // store.getState() = { count: 0, numberOfCalls: 0 }
    
    store.getActions().increment();
    
    // store.getState() = { count: 1, numberOfCalls: 1 }
    
    store.getActions().addX(10);
    
    // store.getState() = { count: 11, numberOfCalls: 2 }
    
    

    This can be used with React hooks with these effects

    export const useGlobalState: () => [State, Actions] = () => {
        const [storeState, setStore] = React.useState(store.getState());
        React.useEffect(() => {
            const callback = () => setStore(store.getState());
            store.addChangeListener(callback);
            return () => store.removeChangeListener(callback);
        }, []);
        return [storeState, store.getActions()];
    };
    
    export const useDispatchListener = (actions: Partial<Actions>, deps: any[]) => {
        React.useEffect(() => {
            store.subscribe(actions);
            return () => store.unsubscribe(actions);
        }, deps);
    }
    
    

    Keywords

    none

    Install

    npm i @cimacmillan/refunc

    DownloadsWeekly Downloads

    0

    Version

    1.0.3

    License

    GPL-3.0-or-later

    Unpacked Size

    63.8 kB

    Total Files

    23

    Last publish

    Collaborators

    • cimacmillan