This library aims to abstract away the manual creation of lenses or state selectors. In redux we might have an initial state that looks like the following:
const initialState = {
someList: [],
someOtherProperty: 1,
someNestedProperty: {
someNestedValue: 1,
},
}
Now we could access these properties a variety of ways.
// Normal Dot Properties
const someList = initialState.someList;
const someNestedValue = initialState.someList.someNestedValue;
// Object Destructuring
const { someList, someNestedProperty: { someNestedValue } } = initialState;
But what if the structure of our state changes? This approach will result in an undefined value which could break the UI.
import initialState from './state';
// function to retrieve value with fallback
const someNestedProperty = (state) => {
const { someNestedProperty } = state;
return state || initialState.someNestedProperty;
};
const someNestedValue = (state) => {
const { someNestedValue } = someNestedProperty(state);
return someNestedValue || initialState.someNestedProperty.someNestedValue;
};
This approach is better as it creates a fallback at each level of nesting. But to get a value on state shape change the selectors need to be re-written. Also this does not provide a method by which we can set a value.
Given that we always know our initial state shape in redux we can create a lens for every property in an object.
import lenscrafter from 'lenscrafter'
const initialState = {
someList: [],
someOtherProperty: 1,
someNestedProperty: {
someNestedValue: 1,
},
}
const currentState = {
someList: [],
someOtherProperty: 1,
someNestedProperty: {
someNestedValue: 'New Value',
},
}
// create getter and setter pairs for every property
const ourSpecialLens = lenscrafter(initialState);
ourSpecialLens.props.someNestedValue.get(/* state */); // 1
ourSpeicalLens.props.someNestedValue.get(currentState); // 'New Value'
using this method, the state retrieval process can be simplified into the one liner above.
It can be ensured that when getting state, a value will always be returned as a fallback instead of undefined
.
object
: The object that the lens should be created for.
object
: The object that the property should be retrieved for. If the object does not have the property it will fallback to the value of the property in the initial call to lenscrafter
.
Returns the current value of the object at the specified property
If an object passed into lenscrafter contains a duplicate property. For example:
const myObject = {
id: 1,
item1: {
id: 2,
},
item2: {
id: 3,
}
}
Instead of the id being acessible on the root, it will instead be accessed on it's immediate parent.
lens.props.item1.id.get()
Deeply nested properties will resolve in a similar way
const myObject = {
id: 1,
x: {
y: {
item1: {
id: 2,
},
item2: {
id: 3,
}
}
}
}
lens.props.item1.id.get()
value
: The value to set the property to.
object
: The object for which the value should be set.
Returns a new object with the specified property updated to the specified value
Returns the lens used for getting and setting, this is useful for further composition.
propsArray: Array<string>
: An array of properties to get the value of
object
: The object for which the values should be retrieved
Returns the initial object passed into lenscrafter(object)
To install: npm install --save lenscrafter
Run tests and compile the code with node make
. For tests that also watch the files the karma.conf
can be updated to
be false
for single run, this is particularly useful for development.
Code can be built using node make minify
.
See the scripts
in the package.json for other useful commands.