New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

repatch

Package Overview
Dependencies
Maintainers
1
Versions
42
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

repatch

Dispatch reducers

  • 1.0.8
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
175
decreased by-46.81%
Maintainers
1
Weekly downloads
 
Created
Source

Repatch

Dispatch reducers

Redux has a verbose action management. The most of redux projects do not need sctrict action administration. Action types, action creators and the reducer's action handlers are mutually assigned to each other. Repatch's purpose is creating actions briefly.

The simplest way to keep immutable action controlled dataflow is dispatching pure functions (as reducers) to the store.

store.dispatch(state => ({ ...state, counter: state.counter + 1 }));

In this terminology, an action is a function that returns a reducer:

const increment = amount => state => ({
  ...state,
  counter: state.counter + amount
});

store.dispatch(increment(42));

Installation

npm install --save repatch

API Reference

Examples

Articles

Repatch - the simplified Redux

How to use

import Store from 'repatch';

const store = new Store(initialState);

In CommonJS format you should use:

const Store = require('repatch').default;

Repatch's interface is very similar to Redux, therefore you can use with react-redux.

const unsubscribe = store.subscribe(() => console.log(store.getState()));

store.dispatch(resolveFetchingUsers(users));

unsubscribe();

Sub-reducers

We do not need to reduce always the whole state of the store. Repatch also offers a way to combine sub-reducers, those describe a deeply nested property in the state. We just define a function that takes a nested reducer as argument, and returns a reducer that reduces the whole state:

const reduceFoo = fooReducer => state => ({
  ...state,
  bar: {
    ...state.bar,
    foo: fooReducer(state.bar.foo)
  }
});

Using that we can define easily an action, that sets an x property in the foo object:

const setX = x => reduceFoo(state => ({ ...state, x }));

Middlewares

A repatch middleware takes the store instance and the previous reducer and returns a new reducer:

(Store, Reducer): Reducer

Use the addMiddleware method to chaining middlewares:

const store = new Store(initialState)
  .addMiddleware(mw1)
  .addMiddleware(mw2, mw3);

Async actions

The thunk middleware is useful for handling async actions similar to redux-thunk.

import Store, { thunk } from 'repatch';

const store = new Store(initialState).addMiddleware(thunk);

In thunk async actions reducer returns a function (delegate):

const updateUser = delta => state => async (dispatch, getState) => {
  const editedUserId = getState().editedUser;
  dispatch(toggleSpinner(true));
  await api.updateUser(editedUserId, delta);
  await dispatch(fetchUsers());
  dispatch(toggleSpinner(false));
};

It is possible to embed async actions within each other too and awaiting their resolving:

await dispatch(fetchUsers());

You can access thunk even as static member of the Store: Store.thunk

Injecting extra argument

It is possible to inject extra arguments into async actions:

import Store, { thunk } from 'repatch';
import api from './api';
import hashHistory from 'react-router';

const store = new Store(initialState)
  .addMiddleware(thunk.withExtraArgument({ api, hashHistory }));

Then you can access these arguments in your delegates:

const updateUser = delta => state =>
  async (dispatch, getState, { api, hashHistory }) => {
    // ...
  }

This way you can keep your async actions independently from outer instances. This practice is useful for testing.

Testing

Sync actions

Sync actions' testing is easy:

import * as assert from 'assert';
import { changeName } from './actions';

// ...

it('changeName', () => {
  const state = { name: 'john' };
  const nextState = changeName('jack')(state);
  assert.strictEqual(nextState.name, 'jack');
});

Async actions

For async action tests you need to instantiate the Store:

import Store, { thunk } from 'repatch';
import * as assert from 'assert';
import { fetchUsers } from './actions';

const mockUsers = [{ username: 'john' }];
const mockApi = {
  getUsers: () => Promise.resolve(mockUsers)
}

// ...

it('fetchUsers', async () => {
  const state = { users: [] };
  const store = new Store(state)
    .addMiddleware(thunk.withExtraArgument({ api: mockApi }));
  await store.dispatch(fetchUsers());
  const nextState = store.getState();
  assert.deepEqual(nextState.users, mockUsers);
});

License

MIT

Developed by

JayStack

Keywords

FAQs

Package last updated on 16 Aug 2017

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc