Skip to content

dmitrii-khr/immutable-selectors

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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.

About

immutable-selectors npm package

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published