immutable-lens
Type-safe Lens API for immutable updates in deep data structures
Features
- No mutations (obviously...)
- Human-friendly API
- Update your Redux store, your React component state, your Immutable.js collection... Whatever !
- Bring in your favorite libraries (Ramda, lodash-fp, date-fns...)
- Optimized for the strict equality checks performed in
React.PureComponent
, connect()
... - Written in TypeScript, designed for maximal type-safety
Quickstart
Install
$ npm i -S immutable-lens
Create lens
import {createLens} from 'immutable-lens'
type State = {
user: {
name: string
age: number
}
}
const lens = createLens<State>()
Focus
const userLens = lens.focusPath('user')
const nameLens = userLens.focusPath('name')
const ageLens = lens.focusPath('user', 'age')
Read
const state: State = {
user: {
name: 'Bob',
age: 18
}
}
userLens.read(state)
nameLens.read(state)
Update
const setNameToJohn =
nameLens.setValue('John')
nameLens.update(currentName => 'John')
userLens.setFields({name: 'John'})
userLens.updateFields({name: (currentName) => 'John'})
userLens.updatePartial(user => ({name: 'John'}))
setNameToJohn(state)
Compose updates with pipeUpdaters()
import {createLens, pipeUpdaters} from 'immutable-lens'
type State = {
user: {
name: string
}
}
const state = {
user: {
name: 'Bob',
}
}
const nameLens = createLens<State>().focusPath('user', 'name')
const setNameToJohn = nameLens.setValue('John')
const uppercaseName = nameLens.update(name => name.toUpperCase())
const setNameToJOHN = pipeUpdaters(
setNameToJohn,
uppercaseName
)
const updatedState = setNameToJOHN(state)
Use defaultTo()
to avoid undefined values when reading or updating optional types
import {createLens} from 'immutable-lens'
type State = {
loggedUser?: {
name: string
age: number
}
}
const state = {
}
const nameLens = createLens<State>()
.focusOn('loggedUser')
.defaultTo({name: 'Guest', age: 0})
.focusOn('name')
const name = nameLens.read(state)
const setNameToBob = nameLens.setValue('Bob')
const updatedState = setNameToBob(state)
Focus on array index
import {Lens, createLens} from 'immutable-lens'
type Person = {
name: string
}
type State = {
friends: Person[]
}
const firstFriendLens = createLens<State>()
.focusOn('friends')
.focusIndex(0)
const firstFriend: Person | undefined = firstFriendLens.read({friends: []})