@reduxed/actions v0.1.4
@reduxed/actions
Provides helper for managing Redux state
Written in Typescript and includes types
More features to come (WIP)
Part of @reduxed utilities for Redux.
Assumes the use of ramda, redux-actions and reselect
Table of Contents
Installation
$ yarn add @reduxed/actions
or
$ npm install --save @reduxed/actions
The npm package provides a CommonJS build, a UMD build, as well as an AMD build.
Usage
Component
Binding your redux store to a component with separate actions props and state props:
import { connect } from '@reduxed/actions'
export default connect(mapStateToProps, mapDispatchToProps)
connect is used the same way as connect from react-redux
state will be accessible in the component via input prop, and actions via output props:
export default ({ input, output }) => (
//Component
)
Selector
Create wrapper selectors for a named reducer:
- inputs: parent selector, object containing root selector functions
- output: object containing selectors children of parent selector with key: selector name, value: selector function
- */
import { createSelector } from 'reselect'
import { createWrapperSelectors } from '@reduxed/actions'
const getFriend = ({ friend }) => friend
const parentSelector = createSelector(state => state, getFriend)
const selectors = {
getFirstName: ({ firstName }) => firstName,
getLastName: ({ lastName }) => lastName
}
const namedSelectors = createWrapperSelectors(parentSelector, selectors)
const {
getFirstName,
getLastName
} = namedSelectors
Create selectors from state props
import { createSelector } from 'reselect'
import { createSelectors } from '@reduxed/actions'
const getFriend = ({ friend }) => friend
const parentSelector = createSelector(state => state, getFriend)
const props = [
'firstName',
'lastName'
]
const selectors = createSelectors(parentSelector, props)
const {
getFirstName,
getLastName
} = selectors
Use index as key in a list React component:
import { indexAsKey } from '@reduxed/actions'
const Component = ({ friends }) =>
friends.map(({ firstName }) => firstName)
.map(indexAsKey)
.map(props => <div { ...props }/>)
Use map from ramda with an index:
import { mapIndexed } from '@reduxed/actions'
mapIndexed((x, index) => x * index, [ 1, 2, 3 ]) // => [ 0, 2, 6 ]
Use a tranducer to prevent from using too many loops on an array:
import { transduceIntoArray } from '@reduxed/actions'
const fancyFn = transduceIntoArray(
(x, index) => x * index,
x => x * 2
)
fancyFn([ 1, 2, 3 ]) // => [ 0, 4, 12 ]
Use a tranducer to prevent from using too many loops on an object:
import { transduceIntoObject } from '@reduxed/actions'
const fancyFn = transduceIntoObject(
(x, index) => x * index,
x => x * 2
)
fancyFn({ a: 1, b: 2, c: 3 }) // => { a: 0, b: 4, c: 12 }
Use a curried function to create React components:
import {
createElement,
indexAsKey
} from '@reduxed/actions'
const createComponent = createElement('div')
const Component = ({ friends }) =>
friends.map(({ firstName }) => firstName)
.map(indexAsKey)
.map(createComponent)
Use a curried function to create selectors:
import { createSelector } from '@reduxed/actions'
const createUiSelector = createSelector(state => state.ui)
const getDimensions = createUiSelector(ui => ui.dimensions)
Parse url segments:
import {
getLastSegment,
getUrlSegments
} from '@reduxed/actions'
const resourceUrl = '/resource/id'
getLastSegment(resourceUrl) // => 'id'
getUrlSegments(resourceUrl) // => [ 'resource', 'id' ]
Pick nested properties from an object:
import { pickOnlyTheseKeys } from '@reduxed/actions'
const keysToKeep = [
{ src: 'resource.id' },
{ src: 'data.id', dest: 'dataId' }
]
const pickKeys = pickOnlyTheseKeys(keysToKeep)
pickKeys({ resource: { id: '1' }, data: { id: '2' } }) // => { id: '1', dataId: '2' }
Actions
Create named actions:
import { createActions } from 'redux-actions'
import { createWrapperActions } from '@reduxed/actions'
const creators = createActions('CHANGE_FIRSTNAME', 'CHANGE_LASTNAME')
const wrapperCreators = createWrapperActions('BEST', creators)
const {
changeFirstName,
changeLastName
} = wrapperCreators
Create nested actions:
import { createNestedActions } from '@reduxed/actions'
const nestedCreators = createNestedActions('BEST', [ 'CHANGE_FIRSTNAME', 'CHANGE_LASTNAME' ])
const {
changeFirstName,
changeLastName
} = nestedCreators
Combine actions for use in a reducer:
import { createActions } from 'redux-actions'
import { combineWrapperActions } from '@reduxed/actions'
const creators = createActions('CHANGE_FIRSTNAME', 'CHANGE_LASTNAME')
const combinedActions = combineWrapperActions(creators)
const reducer = handleActions({
[combinedActions]: state => ({ ...state })
}, {})
Reducer
Create a higher order reducer combining multiple reducers:
import { createActions } from 'redux-actions'
import { createReducer } from '@reduxed/actions'
const {
changeFirstName,
changeLastName
} = createActions('CHANGE_FIRSTNAME', 'CHANGE_LASTNAME')
const reducer = handleActions({
[changeFirstName]: (state, { payload }) => payload
}, {})
const wrapperReducer = createReducer({
[changeLastName]: (state, { payload }) => ({ lastName: payload })
}, {
firstName: 'John',
lastName: 'Doe'
}, {
firstName: {
actions: { changeFirstName },
reducer
}
// could contain other reducers
})
Get initial state from a reducer:
import { createAction } from 'redux-actions'
import { getInitialState } from '@reduxed/actions'
const changeLastName = createAction('CHANGE_LASTNAME')
const reducer = handleActions({
[changeLastName]: (state, { payload }) => ({ lastName: payload })
}, {
lastName: 'Doe'
})
getInitialState(reducer) // => { lastName: 'Doe' }