immutable-selectors

1.0.5 • Public • Published

immutable-selectors

travis build status Coverage Status

This package is used for comfort reusable access to parts of deep nested immutable structures. It also allows you to make modification of this structures.

Usage

Example immutable structure

const state = Immutable.fromJS({
  moduleA: {
    foo: {
      id:100500,
      deep:{
        val:500
      },
      message:'SomeStringMessage'
    },
    bar:{}
  },
  moduleB:{}
});

Create selector tree Describe nested selector - object with properties you want to get access:

    const selectors = {
      foo:{
        deep:{val:{}},
        message:{}
      }
    }

Make selectors from this object:

import extendSelecors from 'immutable-selectors';
extendSelecors(selectors, ['moduleA']);

extendSelecors(selectorsTree, [path]) function recursively converts each key in object to a function(state), which returns corresponding part of immutable structure. At the same time, it saves the hierarchy. It is not returns a new selector - object, but it converts selectors object itself. This allows to use intelliSence in most of IDEs.

Use selector

console.log(selectors.foo.message(state)); //SomeStringMessage
console.log(selectors.foo(state)); // Map { "id": 100500, "deep": Map { "val": 500 }, "message": "SomeStringMessage" }
console.log(selectors.foo(state).get('message')); // SomeStringMessage
console.log(selectors.foo.deep.val(state)); // 500

flat option: Each unique key of selectors-tree is dublicated in selectors.flat object:

console.log(selectors.flat.val(state)); //500
console.log(selectors.flat.message(state)); // SomeStringMessage

root option:

const moduleAData = selectors.root(state);
console.log(moduleAData.getIn(['foo', 'id'])); //100500

Modifications Each selector-function in tree has replace(state, newValue) child function, which returns new immutable structure with changed corresponding part.

var newState = selectors.foo.message.replace(state, 'updated message');
console.log(newState.getIn(['moduleA','foo', 'message'])); //updated message
var newState = selectors.flat.val.replace(state, 'new value');
console.log(newState.getIn(['moduleA','foo', 'deep', 'val'])); //new value
var part = selectors.foo(state).asMutable();
part.setIn(['deep', 'val'], 'fivehundred');
var newState = selectors.foo.replace(state, part.asImmutable());
console.log(newState.getIn(['moduleA','foo', 'deep', 'val']));//fivehundred

Parameters

It is possible to use selectors for collection items access (Lists and Maps). You should specify param property in selector-object at collection level.

Example immutable structure

const state = Immutable.fromJS({
  moduleA: {
    bar: {
      listItems: [
        {
          key: 100,
          caption: 'firstListItem',
          deep:{ description:'someText'}
        },
        {
          key: 200,
          caption: 'secondLIstItem'
        }
      ]}}
});

Create selector tree

    const selectors = {
        bar:{
          listItems:{
            param:'x',
            key:{},
            caption:{},
            deep:{description:{}}
          }
        }
    }
 
   extendSelecors(selectors, ['moduleA']);

Use

  console.log(selectors.bar.listItems.caption(state, '1')); //secondLIstItem
  console.log(selectors.flat.key(state, '0')); //100
  console.log(selectors.flat.description(state, '0')); //someText
  console.log(selectors.bar.listItems(state, '1'));//Map { "key": 200, "caption": "secondLIstItem" }
  console.log(selectors.bar.listItems(state));//List [ Map { "key": 100, "caption":...
 

Modifications Use third parameter of replace function to specify collection item.

var newState = selectors.bar.listItems.caption.replace(state, 'updated-first', '0');
console.log(newState.getIn(['moduleA', 'bar', 'listItems', '0', 'caption'])); // updated-first

Use with redux

One of use-cases is to replace redux reducers with action-creators, which generates new global state. Example of action-creator:

export function showMessage(message) {
  return function (dispatch, getState) {
    dispatch({
      type: 'show message',
      setState: selectors.message.replace(getState(), message)
    });
  };
}

Root reducer:

function setStateReducer(state = initialState, action) {
  if (action.setState) {
    return action.setState;
  } else {
    return state;
    // return combinedReducers(state, action);  // You can mix this pattern with classical combineReducers - function.
  }
}

Example of using immutable-selectors with redux without reducers.

Versions

Current Tags

  • Version
    Downloads (Last 7 Days)
    • Tag
  • 1.0.5
    0
    • latest

Version History

Package Sidebar

Install

npm i immutable-selectors

Weekly Downloads

0

Version

1.0.5

License

ISC

Unpacked Size

16.2 kB

Total Files

6

Last publish

Collaborators

  • dmitrii-khr