All Projects → madetheforcebewithyou → redux-knife-manager

madetheforcebewithyou / redux-knife-manager

Licence: MIT license
The lightweight and flexible library for implementing Redux entities with React.

Programming Languages

javascript
184084 projects - #8 most used programming language
Makefile
30231 projects

Projects that are alternatives of or similar to redux-knife-manager

react-workshops
Online react workshops
Stars: ✭ 36 (+12.5%)
Mutual labels:  redux-saga
react-native-ecommerce
E-commerce mobile application developed using React Native 👔 🎩
Stars: ✭ 60 (+87.5%)
Mutual labels:  redux-saga
dva-vue
🌱 Vue and dva-core based
Stars: ✭ 34 (+6.25%)
Mutual labels:  redux-saga
movies
a project build with react、redux、 redux-saga、 express 、mongodb、ssr also ☀️
Stars: ✭ 76 (+137.5%)
Mutual labels:  redux-saga
next-react-boilerplate
🔥 NextJS with additional tech feature like react-boilerplate. Demo >>
Stars: ✭ 20 (-37.5%)
Mutual labels:  redux-saga
react-phoenix-users-boilerplate
Elixir/Phoenix + React + users template/boilerplate.
Stars: ✭ 71 (+121.88%)
Mutual labels:  redux-saga
abilitysheet
This app is ability sheet for beatmania iidx music of level 12.
Stars: ✭ 38 (+18.75%)
Mutual labels:  redux-saga
duxjs
Componentized redux framework
Stars: ✭ 17 (-46.87%)
Mutual labels:  redux-modules
data-flow
frontend data flow explored in React
Stars: ✭ 19 (-40.62%)
Mutual labels:  redux-saga
delivery-app-mobile
🍕React Native food delivery app
Stars: ✭ 143 (+346.88%)
Mutual labels:  redux-saga
marvel-jarvig
Marvel JARVIG (Just A Rather Very Interesting Game) is a game that lets you find and discover Marvel Comics characters based on their name, image and description!
Stars: ✭ 13 (-59.37%)
Mutual labels:  redux-saga
hbb-survey-app
Hatay Municipality Survey Application
Stars: ✭ 18 (-43.75%)
Mutual labels:  redux-saga
nextjs-redux-instagram
🌏 The simple Instagram was written by next.js & redux-saga & recompose
Stars: ✭ 48 (+50%)
Mutual labels:  redux-saga
inside-client
Human Resources Department Tool. https://ifactory-solutions.github.io/inside-client/
Stars: ✭ 42 (+31.25%)
Mutual labels:  redux-saga
react-redux-dashboard
React Redux Dashboard with redux-saga and local-storage support
Stars: ✭ 48 (+50%)
Mutual labels:  redux-saga
youtube-codequinta-redux-saga
Project created during Redux Saga live
Stars: ✭ 36 (+12.5%)
Mutual labels:  redux-saga
react-native-basekit
Basic setup for react-native projects using react-native , redux, redux-sagas, react-navigation
Stars: ✭ 16 (-50%)
Mutual labels:  redux-saga
umi-dva-typescript-mock
基于umi + dva + typescript + mock + antd的react框架,内置PWA
Stars: ✭ 17 (-46.87%)
Mutual labels:  redux-saga
crassa
Create React App Server Side Application
Stars: ✭ 16 (-50%)
Mutual labels:  redux-saga
fhir-app-starter
🔥 Open Source FHIR App project starter. Start building your app right away.
Stars: ✭ 21 (-34.37%)
Mutual labels:  redux-saga

Redux Knife Manager

Build Status Coverage Status Maintainability node version npm version npm monthly download license

Redux Knife Manager is the lightweight library for easily managing, encapsulating and generating the redux entities such as action, reducer, selector and so on.

Redux Knife Manager has following features:

  • It is very suitable for redux, redux-saga and related stacks.
  • Use naming convention to generate the redux action, redux action type and selector automatically.
  • Keep the codebase more cleaner even if cross-container interactions are very often.
  • Prevent the collision of action type constants.
  • Reuse the selector concept in redux containers and redux saga flows.
  • Support universal application.
  • You can focus on redux reducer implementation and testing.

In short, it can be used to reduce the codebase complexity and gain the better convention while developing.

Installation

Please use the following command to install Redux Knife Manager, assume you use the package management system with yarn

yarn add redux-knife-manager redux

or npm.

npm install --save redux-knife-manager redux

Quick start

  1. Consider the counter application, we need to configure the counter knife first.
import { createStore, combineReducers } from 'redux';
import reduxKnifeManager from 'redux-knife-manager';

// 1. Initialize Redux Knife Manager
reduxKnifeManager.initialize();

// 2. Add a knife to Redux Knife Manager
reduxKnifeManager.addKnife('counter', {
  actionMap: ['increase', 'decrease'],
  reducerMap: ({ increase, decrease }) => ({
    [increase]: (state, action) => ({
      num: state.num + action.value,
    }),

    [decrease]: (state, action) => ({
      num: state.num - action.value,
    }),
  }),
  defaultState: {
    num: 0,
  },
});

// 3. reducer can also listen cross-category actions
reduxKnifeManager.addKnife('inverse', {
  actionMap: ['reset'],
  reducerMap: (
    { reset },
    { counter: { increase, decrease } },
  ) => ({
    [counter]: (state, action) => ({
      num: state.num - action.value,
    }),

    [counter]: (state, action) => ({
      num: state.num + action.value,
    }),

    [reset]: () => ({
      num: 0,
    }),
  }),
  defaultState: {
    num: 0,
  },
});

// 4. Configure the redux store
const store = createStore(combineReducers(reduxKnifeManager.getRootReducer()));
  1. After configuring the counter knife, we can now get the counter value and dispatch the increase/decrease action.
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import reduxKnifeManager from 'redux-knife-manager';

// 1. Get the counter knife
const counterKnife = reduxKnifeManager.getKnife('counter');

// 2. Configure the mapStateToProps
function mapStateToProps(state) {
  return {
    num: counterKnife.selector.get(state, 'num'),
  };
}

// 3. Connect to redux
@connect(mapStateToProps)
export default class App extends React.Comopnent {
  static propTypes = {
    dispatch: PropTypes.func,
    num: PropTypes.number,
  };

  onIncrease() {
    // dispatch the increase action
    const { dispatch } = this.props;
    dispatch(counterKnife.action.increase({ value: Math.random() }));
  }

  onDecrease() {
    // dispatch the decrease action
    const { dispatch } = this.props;
    dispatch(counterKnife.action.decrease({ value: 1 }));
  }

  render() {
    const { num } = this.props;

    return (
      <div>
        <button onClick={this.onIncrease}>Increase</button>
        <button onClick={this.onDecrease}>Decrease</button>
        <div>{num}</div>
      </div>
    );
  }
}
  1. The counter knife can be also used in other places, assume you are using redux-saga in asynchronous flow management.
import { takeEvery } from 'redux-saga/effects';
import reduxKnifeManager from 'redux-knife-manager';

const counterKnife = reduxKnifeManager.getKnife('counter');

export default function* counterSaga() {
  yield takeEvery(counterKnife.actionType.increase, function* handleIncrese(action) {
    // do something like print the action value
    console.log(action);
  });
}

Detailed examples

The project takes todoMVC as detailed examples, please refers the examples folder.

API reference

initialize(options)

The function initialize is used to initialize Redux Knife Manager. Since Redux Knife Manager is the single instance, the knives and related entries will be released when initialize has been called.

Arguments

  • options (Object):
    • namespace (String, default: 'app'):
      The namespace is the prefix of top level of redux store to restore the state of knives.

Example

reduxKnifeManager.initialize({
  namespace: 'example',
});

addKnife(category, config)

The function addKnife is used to add a knife to Redux Knife Manager. It will generate the redux entities such as action, reducer, selector automatically by the given config.

Arguments

  • category (String):
    It is the the identifier to associate with the knife.
  • config (Object):
    • actionMap (Array of String):
      Redux Knife Manager will generate collections of action generator and action type which are based on actionMap.
    • reducerMap (Function(actionType, allActionType)):
      Redux Knife Manager will pass generated actions to reducerMap. And it must return the object of definition of reducers which are associated with spicfied actions.
    • defaultState (Object):
      The default state of knife which is associated with category.

Returns

  • Return Knife Object if the knife is configured successfully.
  • Otherwise, undefined.

Example

// 1. Initialize Reudx Knife Manager
reduxKnifeManager.initialize({
  namespace: 'example',
});


// 2. Add a knife to Reudx Knife Manager
reduxKnifeManager.addKnife('counter', {
  actionMap: ['increase', 'decrease'],
  reducerMap: ({ increase, decrease }) => ({
    [increase]: (state, action) => ({
      num: state.num + action.value,
    }),

    [decrease]: (state, action) => ({
      num: state.num - action.value,
    }),
  }),
  defaultState: {
    num: 0,
  },
});

// 3. reducer can also listen cross-category actions
reduxKnifeManager.addKnife('inverse', {
  actionMap: ['reset'],
  reducerMap: (
    { reset },
    { counter: { increase, decrease } },
  ) => ({
    [increase]: (state, action) => ({
      num: state.num - action.value,
    }),

    [decrease]: (state, action) => ({
      num: state.num + action.value,
    }),

    [reset]: () => ({
      num: 0,
    }),
  }),
  defaultState: {
    num: 0,
  },
});

// 4. Configure the redux store
const store = createStore(combineReducers(reduxKnifeManager.getRootReducer()));

/* 6. The redux store will be as follow:
 * {
 *   example: {
 *     counter: {
 *       num: 0,
 *     },
 *     inverse: {
 *       num: 0,
 *     },
 *  }
 */

getKnife(category)

The function addKnife is used to retrieve a knife from Redux Knife Manager.

Arguments

  • category (String):
    It is the the identifier to retrieve the knife.

Returns

  • Return the Knife Object which is associated with the given category.
  • Otherwise, it will return undefined if the knife is not exist.
  • Knife Object:
    • selector (Object):
      The collection of selector. It will generate the get method to retrieve the whole state, and selectors to retr.
    • actionType (Object):
      The collection of action type, and the properties of actionType are based on actionMap.
    • action (Object):
      The collection of action generator, and the properties of action are based on actionMap. In order to simplify the interface, the action generator do only accept the payload with the plain object, and it will construct the simple action generator. The definition of action generator is as follow:
      action[name] = (payload = {}) => ({
        type: autoGeneratedConstant,
        ...payload,
      });

Example

// 1. Initialize Redux Knife Manager
reduxKnifeManager.initialize({
  namespace: 'example',
});

// 2. Add a knife to Redux Knife Manager
reduxKnifeManager.addKnife('counter', {
  actionMap: ['increase', 'decrease'],
  reducerMap: ({ increase, decrease }) => ({
    [increase]: (state, action) => ({
      num: state.num + action.value,
    }),

    [decrease]: (state, action) => ({
      num: state.num - action.value,
    }),
  }),
  defaultState: {
    num: 0,
  },
});

// 3. Configure the redux store
const store = createStore(combineReducers(reduxKnifeManager.getRootReducer()));

const counterKnife = reduxKnifeManager.getKnife('counter');
// 4. The collection of action type
// You can get the action type of increase via the following statement
console.log(counterKnife.actionType.increase);

// You can get the action type of decrease via the following statement
console.log(counterKnife.actionType.decrease);


// 5. The collection of action
// You can get the increase action via the following statement
console.log(counterKnife.action.increase({ value: 1 }));

// You can get the decrease action via the following statement
console.log(counterKnife.action.decrease({ value: 1 }));


// 6. The collection of selector
// You can get the whould state of counterKnife via the following statement
// and the value should be { num: 0 }
console.log(counterKnife.selector.get(store.getState()));

// You can get the num value of counterKnife via the following statement
// and the value should be 0
console.log(counterKnife.selector.get(store.getState(), 'num'));


// 7. Reducer should also work well
store.dispatch(counterKnife.action.increase({ value: 10 }));

// You can get the num value of counterKnife via the following statement
// and the value should be 10
console.log(counterKnife.selector.get(store.getState(), 'num'));

getKnives()

The function getKnives will return all knives in Redux Knife Manager.

Returns

  • Return the Object which is consist of knives which are associated their category.

Example

// 1. Initialize Redux Knife Manager
reduxKnifeManager.initialize();

// 2. Add knives to Redux Knife Manager
reduxKnifeManager.addKnife('k1', { ... });
reduxKnifeManager.addKnife('k2', { ... });
reduxKnifeManager.addKnife('k3', { ... });

const knives = reduxKnifeManager.getKnives();

/*
 * The value of knives is as follow:
 * {
 *    k1: { ... },
 *    k2: { ... },
 *    k3: { ... }
 *  }
 */

getRootReducer()

The function getRootReducer is used to get combined reducers of knives. It should be used to configure with redux store.

Returns

  • Return the Object of combined reducer of knives which are associated with namespace.

Example

// 1. Initialize Redux Knife Manager
reduxKnifeManager.initialize();

// 2. Add knives to Redux Knife Manager
reduxKnifeManager.addKnife('k1', { ... });
reduxKnifeManager.addKnife('k2', { ... });
reduxKnifeManager.addKnife('k3', { ... });

// 3. Configure the redux store
const store = createStore(combineReducers(reduxKnifeManager.getRootReducer()));

Todo

  • Adding the example for integrating with redux-saga
  • Adding the example for integrating with re-select

Inspired by

License

This project is licensed under the MIT license, Copyright (c) 2018 madetheforcebewithyou. For more information, please see LICENSE.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].