ded

deduce

Ridiculously easy JavaScript state containers with action methods.

Showing:

Popularity

Downloads/wk

0

GitHub Stars

7

Maintenance

Last Commit

4yrs ago

Contributors

1

Package

Dependencies

0

License

MIT

Type Definitions

Tree-Shakeable

Yes?

Categories

Readme

deduce

NPM version Downloads Build Status Coverage Status Tip

Ridiculously easy JavaScript state containers with reducer methods. Like Redux without all of the boilerplate.

Install

npm install --save deduce

Usage

// reducers.js

export function increment(state, val = 1) {
    return state + val;
}

export function decrement(state, val = 1) {
    return increment(state, -val);
}

// store.js

import deduce from 'deduce';
import * as reducers from './reducers';

const store = deduce(1, reducers);

store.addListener(() => {
    console.log(store.state);
});

store.increment();  // -> 2
store.increment(2); // -> 4
store.decrement();  // -> 3
store.decrement(2); // -> 1

API

deduce(initialState, reducers) : Store

  • initialState {*}
  • reducers {Object<String,Function>}

Store

.state

Current state of the store.

const store = deduce({ foo: 1 });

console.log(store.state); // -> { foo: 1 }

.addReducers(reducers): Store

  • reducers {Object<String,Function>}

Registers reducers to modify the state. Chainable.

store.addReducers({
    increment(state, val) {
        return {
            ...state,
            foo: state.foo + val,
        };
    },
});

.addReducersFor(property, reducers): Store

  • property {String}
  • reducers {Object<String,Function>}

Registers reducers to modify a specific state property. Chainable.

store.addReducersFor('foo', {
    increment(state, val) {
        return state + val;
    },
});

.addListener(callback): Function

  • callback {Function}

Adds a listener to be called any time the state is updated. Returns a function to remove the listener.

const removeListener = store.addListener(() => {
    console.log(store.state);
});

store.increment();

Why?

The typical Redux patterns entail a lot of boilerplate. The documented and accepted patterns for reducing boilerplate really just swap one kind for another:

Redux Example

Consider the following Redux example that creates a store with two numbers: foo which may be incremented and bar which may be decremented.

// foo

const FOO_INCREMENT = 'FOO_INCREMENT';

const fooInitial = 0;

const fooReducers = {
    [FOO_INCREMENT]: (state = fooInitial, action) {
        return state + action.payload;
    }
};

function foo(state = {}, action) {
    if (action.type in fooReducers) {
        return fooReducers[action.type](state, action);
    }

    return state;
}

function createFooIncrementAction(payload) {
    return {
        type: FOO_INCREMENT,
        payload
    };
}

// bar

const BAR_DECREMENT = 'BAR_DECREMENT';

const barInitial = 0;

const barReducers = {
    [BAR_DECREMENT]: (state = barInitial, action) {
        return state - action.payload;
    }
};

function bar(state, action) {
    if (action.type in barReducers) {
        return barReducers[action.type](state, action);
    }

    return state;
}

function createBarDecrementAction(payload) {
    return {
        type: BAR_DECREMENT,
        payload
    };
}

// store

import { createStore, combineReducers } from 'redux';

const reducer = combineReducers({ foo, bar });
const store = createStore(reducer, {});

// application

store.dispatch(createFooIncrementAction(1));
store.dispatch(createBarDecrementAction(1));

console.log(store.getState());
// {
//   foo: 1,
//   bar: -1
// }

Split that up into modules and you can see how new-comers could easily be overwhelmed when the underlying principles are beautifully clean and simple.

Deduce Example

Compare the above with this deduce example that does the same thing:

// foo

const fooInitial = 0;

const fooReducers = {
    incrementFoo(state = fooInitial, val) {
        return state + val;
    }
};

// bar

const barInitial = 0;

const barReducers = {
    decrementBar(state = barInitial, val) {
        return state - val;
    }
};

// store

import deduce from 'deduce';

const store = deduce()
    .addReducersFor('foo', fooReducers)
    .addReducersFor('bar', barReducers);

// application

store.incrementFoo(1);
store.decrementBar(1);

console.log(store.state);
// {
//   foo: 1,
//   bar: -1
// }

Contribute

Standards for this project, including tests, code coverage, and semantics are enforced with a build tool. Pull requests must include passing tests with 100% code coverage and no linting errors.

Test

$ npm test

MIT © Shannon Moeller

Rate & Review

Great Documentation0
Easy to Use0
Performant0
Highly Customizable0
Bleeding Edge0
Responsive Maintainers0
Poor Documentation0
Hard to Use0
Slow0
Buggy0
Abandoned0
Unwelcoming Community0
100
No reviews found
Be the first to rate

Alternatives

No alternatives found

Tutorials

No tutorials found
Add a tutorial