Socket
Socket
Sign inDemoInstall

redux-nestprops-reducer

Package Overview
Dependencies
0
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    redux-nestprops-reducer

A reducer handling a nested property reduces complexity in your code.


Version published
Weekly downloads
10
Maintainers
1
Created
Weekly downloads
 

Readme

Source

redux-nestprops-reducer v1.0.9

It makes a complex reducer simpler.

If you want to change the disabled flag of a one of the comments of the state below to true,

{
  articles: Map([
    ['Sea', { title: '...', comments: List([{ id: 1, disabled: false  }, { id: 2, disabled: false }]) }],
    ['Sports', { title: '...', comments: List([{ id: 1, disabled: false }, { id: 2, disabled: false }]) }]
  ])
}

define the reducer

const DISABLE = 'DISABLE';
const commentReducer = (state = {}, action) => {
  switch(action.type) {
    case DISABLE:
      return {
        ...state,
        disabled: true,
      };
    default:
      return state;
  }
};

...

combineReducers({
  articles: nestpropsReducer(commentReducer, [ENABLE, DISABLE])(
    (state, action) => state.findKey((v, k) => k === action.category),
    'comments',
    (state, action) => state.findIndex(s => s.id === action.id),
  ),
}),

...
// then dispatch the action
store.dispatch({ type: DISABLE, category: 'Sea', id: 2 });
/*
{
  articles: Map([
    ['Sea', { title: '...', comments: List([{ id: 1, disabled: false  }, { id: 2, disabled: true }]) }],
    ['Sports', { title: '...', comments: List([{ id: 1, disabled: false }, { id: 2, disabled: false }]) }]
  ])
}
*/

Installation

Using npm:

$ npm i --save redux-nestprops-reducer

Usage

import nestpropsReducer, /* optional: { reduceReducers } */ from 'redux-nestprops-reducer';
// var nestpropsReducer = require('redux-nestprops-reducer');
// var reduceReducers = require('redux-nestprops-reducer').reduceReducers;

/**
・whitelist actions are actions of the reducer.
・identifiers can be string, number, or function. The function must return an identifier of the parent object.
*/
const reducer = nestpropsReducer(reducer, [whitelist actions], initialState)(identifiers);

Case: using a reducer for multiple objects.

const nestpropsReducer = require('redux-nestprops-reducer');
const createStore = require('redux').createStore;
const combineReducers = require('redux').combineReducers;

//--- Sample state
const complexState = {
  allArticles: [
    { id: 1, value: 1 },
    { id: 2, value: 2, popular: false },
    { id: 3, value: 3 },
  ],
  popularArticles: [
    { id: 2, value: 2, popular: false },
  ],
};

//--- Sample reducer
const SET_POPULAR = 'SET_POPULAR';
const articleReducer = (state = {}, action) => {
  switch(action.type) {
    case SET_POPULAR:
      return {
        ...state,
        popular: action.popular,
      };
    default:
      return state;
  }
};

const articlesReducer = nestpropsReducer(articleReducer, [SET_POPULAR])
  ((state, action) => state.findIndex(f => f.id === action.id));

const store = createStore(combineReducers({
    allArticles: articleReducer,
    popularArticles: articleReducer,
}), complexState);


const action = { type: SET_POPULAR, id: 2, popular: true };
store.dispatch(action);

console.log(store.getState());
/*
{
  allArticles: [
    { id: 1, value: 1 },
    { id: 2, value: 2, popular: true },
    { id: 3, value: 3 },
  ],
  popularArticlues: [
    { id: 2, value: 2, popular: true },
  ],
};
*/

Case: applying multiple reducers to a same prop

Use reduceReducers

const nestpropsReducer = require('redux-nestprops-reducer');
const reduceReducers = require('redux-nestprops-reducer').reduceReducers;

const complexState = {
  articles: Map([
    ['Sea', { title: '...', comments: List([{ id: 1, disabled: false  }, { id: 2, disabled: false }]) }],
    ['Sports', { title: '...', comments: List([{ id: 1, disabled: false }, { id: 2, disabled: false }]) }],
  ]),
};

const CHANGE_CATEGORY = 'CHANGE_CATEGORY';
const articleReducer = (state = Map(), action) => {
  switch(action.type) {
    case CHANGE_CATEGORY:
      const orig = state.get(action.before);
      return state.remove(action.before).set(action.after, orig);
    default:
      return state;
  }
};

const articlesReducer = nestpropsReducer(commentReducer, [COMMENT_DISABLED]);
const store = createStore(
  combineReducers({
    articles: reduceReducers(
      articleReducer,
      /*
      fooReducer,
      barReducer,
      */
      articlesReducer(
        'Sea',
        'comments',
        (state, action) => state.findIndex(s => s.id === action.id),
      ),
    ),
  }),
  complexState,
);

Case: Handling nested arrays

const complexState = {
  categories: [
    {
      category: 'Sea',
      popularArticlues: [{ id: 2, value: 2, popular: false }],
    },
    {
      category: 'Sports',
      popularArticlues: [{ id: 2, value: 2, popular: false }],
    },
  ]
};

//--- Sample reducer
const SET_POPULAR = 'SET_POPULAR';
const articleReducer = (state = {}, action) => {
  switch(action.type) {
    case SET_POPULAR:
      return {
        ...state,
        popular: action.popular,
      };
    default:
      return state;
  }
};
const articlesReducer = nestpropsReducer(articleReducer, [SET_POPULAR]);

const store = createStore(
  combineReducers({
    categories: articlesReducer(
      (state, action) => state.findIndex(s => s.category === action.category),
      'popularArticlues',
      (state, action) => state.findIndex(s => s.id === action.id)
    ),
  }),
complexState);
const action = { type: SET_POPULAR, category: 'Sports', id: 2, popular: true };
store.dispatch(action);
console.log(store.getState());
/*
{
  categories: [
    {
      category: 'Sea',
      popularArticlues: [{ id: 2, value: 2, popular: false }],
    },
    {
      category: 'Sports',
      popularArticlues: [{ id: 2, value: 2, popular: true }],
    },
  ]
}
*/

// Identifier can be null:
const store = createStore(
  combineReducers({
    categories: articlesReducer(
      null, // null indicates that the list('categories list') may need to be applied an action.
      'popularArticlues',
      (state, action) => state.findIndex(f => f.id === action.id)
    ),
  });
});
const action = { type: SET_POPULAR, category: 'Sports', id: 2, popular: true };
store.dispatch(action);
console.log(store.getState());
/*
{
  categories: [
    {
      category: 'Sea',
      popularArticlues: [{ id: 2, value: 2, popular: true }],
    },
    {
      category: 'Sports',
      popularArticlues: [{ id: 2, value: 2, popular: true }],
    },
  ]
}
*/

Case: Traversing Immutable maps and lists

const complexState = {
  articles: Map([
    ['Sea', { title: '...', comments: List([{ id: 1, disabled: false  }, { id: 2, disabled: false }]) }],
    ['Sports', { title: '...', comments: List([{ id: 1, disabled: false }, { id: 2, disabled: false }]) }],
  ]),
};

const COMMENT_DISABLED = 'COMMENT_DISABLED';
const commentReducer = (state = {}, action) => {
  switch(action.type) {
    case COMMENT_DISABLED:
      return {
        ...state,
        disabled: true,
      };
    default:
      return state;
  }
};

const articlesReducer = nestpropsReducer(commentReducer, [COMMENT_DISABLED]);
const store = createStore(
  combineReducers({
    articles: articlesReducer(
      'Sea',
      'comments',
      (state, action) => state.findIndex(s => s.id === action.id),
    ),
  }),
  complexState,
);
const action = { type: COMMENT_DISABLED, id: 2 };
store.dispatch(action);
console.log(store.getState());
/*
{
  articles: Map([
    ['Sea', { title: '...', comments: List([{ id: 1, disabled: false  }, { id: 2, disabled: true }]) }],
    ['Sports', { title: '...', comments: List([{ id: 1, disabled: false }, { id: 2, disabled: false }]) }],
  ]),
}
*/

Keywords

FAQs

Last updated on 29 Nov 2017

Did you know?

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc