GithubHelp home page GithubHelp logo

moducks / moducks Goto Github PK

View Code? Open in Web Editor NEW
74.0 5.0 3.0 270 KB

Ducks (Redux Reducer Bundles) + Redux-Saga = Moducks

License: MIT License

JavaScript 100.00%
ducks redux-actions redux-saga redux moducks

moducks's Introduction

Moducks

moducks

npm version Build Status

Ducks (Redux Reducer Bundles) + Redux-Saga = Moducks

Getting Started

Installing

npm install moducks

Contents

Motivation

Please consider the following fake API:

import { delay } from 'redux-saga'

export const fetchRandomUser = async () => {

  await delay((0.3 + Math.random()) * 1000)

  if (Math.random() < 0.2) {
    // Sometimes it fails
    const faces = ['xD', ':D', ':(']
    throw new Error(`503 Service Unavailable ${faces[Math.floor(Math.random() * faces.length)]}`)
  }

  const users = [
    { name: 'John' },
    { name: 'Mary' },
    { name: 'Bob' },
    { name: 'Cathy' },
    { name: 'Mike' },
  ]

  return users[Math.floor(Math.random() * users.length)]
}

Without moducks, you have to define lengthy definitions for each module.

import { call, put, takeEvery } from 'redux-saga/effects'
import { fetchRandomUser } from '../api'

const LOAD = '@@myApp/randomUser/LOAD'
const LOAD_SUCCESS = '@@myApp/randomUser/LOAD_SUCCESS'
const LOAD_FAILURE = '@@myApp/randomUser/LOAD_FAILURE'
const CLEAR = '@@myApp/randomUser/CLEAR'

export const load = () => ({ type: LOAD })
const loadSuccess = data => ({ type: LOAD_SUCCESS, payload: data })
const loadFailure = error => ({ type: LOAD_FAILURE, payload: error, error: true })
export const clear = () => ({ type: CLEAR })

const initialState = {
  users: [],
  errors: [],
  pendingCounts: 0,
}

export default (state = initialState, { type, payload }) => {
  switch (type) {

    case LOAD:
      return {
        ...state,
        pendingCounts: state.pendingCounts + 1,
      }

    case LOAD_SUCCESS:
      return {
        ...state,
        users: [ ...state.users, payload.name ],
        pendingCounts: state.pendingCounts - 1,
      }

    case LOAD_FAILURE:
      return {
        ...state,
        errors: [ ...state.errors, payload.message ],
        pendingCounts: state.pendingCounts - 1,
      }

    case CLEAR:
      return {
        ...state,
        users: [],
        errors: [],
      }

    default:
      return state
  }
}

export const sagas = {

  load: takeEvery(LOAD, function* (action) {
    try {
      yield put(loadSuccess(yield call(fetchRandomUser)))
    } catch (e) {
      yield put(loadFailure(e))
    }
  }),

}

With moducks, module definition will be extremely simple. The following snippet is equivalent to the above.

import Moducks from 'moducks'
import * as effects from 'redux-saga/effects'
import { fetchRandomUser } from '../api'

const moducks = new Moducks({ effects, appName: 'myApp' })

const initialState = {
  users: [],
  errors: [],
  pendingCounts: 0,
}

const {
  randomUser, sagas,
  load, loadSuccess, loadFailure, clear,
} = moducks.createModule('randomUser', {

  LOAD: {
    reducer: state => ({
      ...state,
      pendingCounts: state.pendingCounts + 1,
    }),
    saga: function* (action) {
      return loadSuccess(yield effects.call(fetchRandomUser))
    },
    onError: (e, action) => loadFailure(e),
  },

  LOAD_SUCCESS: (state, { payload: user }) => ({
    ...state,
    users: [ ...state.users, user.name ],
    pendingCounts: state.pendingCounts - 1,
  }),

  LOAD_FAILURE: (state, { payload: e }) => ({
    ...state,
    errors: [ ...state.errors, e.message ],
    pendingCounts: state.pendingCounts - 1,
  }),

  CLEAR: state => ({
    ...state,
    users: [],
    errors: [],
  }),

}, initialState)

export default randomUser
export { sagas, load, clear }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.