@warren-bank/unified-redux-react-hook
v1.0.11
Published
React custom hooks that enhance 'redux-react-hook' to unify Redux and React 'dispatch' methods with a common API.
Downloads
4
Readme
unified-redux-react-hook
React custom hooks that enhance 'redux-react-hook' to unify Redux and React dispatch
methods with a common API.
CommonJS module
Install:
npm install --save '@warren-bank/unified-redux-react-hook'
Usage:
// full list of module exports
const {StoreContext, addDispatch, removeDispatch, useDispatch, useReduxDispatch, useReduxMappedState, createReduxSelector} = require('@warren-bank/unified-redux-react-hook')
// initialize Redux store
// make context containing Redux store the root component in React hierarchy
const {createStore} = require('redux')
const React = require('react')
const ReactDOM = require('react-dom')
const {StoreContext} = require('@warren-bank/unified-redux-react-hook')
const reduxStore = createStore(reduxReducer)
ReactDOM.render(
<StoreContext.Provider value={reduxStore}>
<App />
</StoreContext.Provider>,
document.getElementById('root')
)
// add React dispatch method
const {useReducer} = require('react')
const {useDispatch} = require('@warren-bank/unified-redux-react-hook')
const [reactState, reactDispatcher] = useReducer(reactReducer, reactInitialState)
const unifiedDispatcher = useDispatch(reactDispatcher)
// use unified dispatch method
const {useDispatch} = require('@warren-bank/unified-redux-react-hook')
const unifiedDispatcher = useDispatch()
const action = {type: 'ADD_TODO', payload: 'buy milk'}
unifiedDispatcher(action)
Browser bundle
Install:
<!-- dependency: React must be loaded before bundle -->
<!-- version: bundle is obtained from npm @ semantic version '1.0.11', which corresponds to git tag 'unified-redux-react-hook/v01.00.11' -->
<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/@warren-bank/[email protected]/dist/unified-redux-react-hook.min.js"></script>
Usage:
// full list of module exports
const {StoreContext, addDispatch, removeDispatch, useDispatch, useReduxDispatch, useReduxMappedState, createReduxSelector} = window.UnifiedReduxReactHook
API:
useDispatch()
- input:
- optional spread list of React dispatch function(s)
- this is the preferred way to register React dispatch function(s)
- it will automatically unregister these function(s) when the component unmounts
- optional spread list of React dispatch function(s)
- output:
- unified
dispatch
function- any action passed to this function will be forwarded to:
- the global Redux store dispatch function
- all registered React dispatch function(s)
- any action passed to this function will be forwarded to:
- unified
- input:
addDispatch()
- input:
- exactly one React dispatch function
- it will not be automatically unregistered, which could lead to memory leaks if you're not careful
- you are responsible for calling
removeDispatch()
when the component unmounts
- exactly one React dispatch function
- output:
- the count of all registered React functions
- input:
removeDispatch()
- input:
- exactly one React dispatch function, which is equal (by
===
reference equality) to one that had previously been passed toaddDispatch()
- exactly one React dispatch function, which is equal (by
- output:
- the count of all registered React functions
- input:
useReduxDispatch()
- input:
- none
- output:
- Redux dispatch function
- note:
- alias for:
require('redux-react-hook').useDispatch
- alias for:
- input:
useReduxMappedState()
- input:
- function:
(state) => value
- function:
- output:
value
- note:
- alias for:
require('redux-react-hook').useMappedState
- alias for:
- input:
createReduxSelector()
- input:
(...inputSelectors, resultFunc, options)
inputSelectors
- [required] a list of functions or Array(s) of functions
- input (to each):
- the 1st input parameter to each function is the global Redux state
- subsequent input parameters are copied from the user-supplied input when invoked
- output (from each):
- a derived value that is relatively inexpensive to compute
- input (to each):
- [required] a list of functions or Array(s) of functions
resultFunc
- [required] a function
- input:
- the derived values as output from
inputSelectors
- the derived values as output from
- output:
- a derived value that is relatively expensive to compute
- input:
- [required] a function
options
- [optional] an Object
- key:
equality
- type: Object || String || Number || null
- Object:
- shape:
{ equality: { forceUpdate: [], recalculate: '' } }
- key:
forceUpdate
- an Array of: String || Integer || null
- length of Array should match the number of
inputSelectors
- each value in the Array corresponds to one
inputSelector
- each value in the Array corresponds to one
- all
inputSelectors
execute every time the global Redux state changes - the previous result of each
inputSelector
is compared to the new result - if the values are determined to be different, then the React component will re-render
- the purpose of this value is to configure how equality is determined
null
represents the default behavior, which is to compare values by strict reference equality (===
)- valid String values include:
'deep'
and'shallow'
- an Integer value results in a
'shallow'
comparison that is allowed to recurse up to the specified maximum depth
- length of Array should match the number of
- shortcut: String || Integer || null
- this value is applied to all
inputSelectors
- this value is applied to all
- default value: null
- an Array of: String || Integer || null
- key:
recalculate
- String || Integer || null
- the results of all
inputSelectors
are determined every time the React component renders- note:
inputSelectors
are memoized and only execute when either the global Redux state changes, or the value of any input parameter changes
- note:
- the previous results are compared to the new results
- if the values are determined to be different, then
resultFunc
will execute- otherwise, the memoized result is reused
- the purpose of this value is to configure how equality is determined
null
represents the default behavior, which is to compare values by strict reference equality (===
)- valid String values include:
'deep'
and'shallow'
- an Integer value results in a
'shallow'
comparison that is allowed to recurse up to the specified maximum depth
- the results of all
- default value: null
- String || Integer || null
- shape:
- String || Number || null:
- shortcut:
- this value is applied to
forceUpdate
andrecalculate
- this value is applied to
- shortcut:
- Object:
- type: Object || String || Number || null
- key:
- [optional] an Object
- output:
- a function
- when invoked:
- any parameters passed into this function will also be passed as input parameters to all
inputSelectors
following the Redux state - all
inputSelectors
are invoked to obtain the corresponding list of derived values- note:
inputSelectors
are memoized and only execute when either the global Redux state changes, or the value of any input parameter changes
- note:
resultFunc
is invoked- note:
resultFunc
is memoized and only executes when its input parameters change
- note:
- any parameters passed into this function will also be passed as input parameters to all
- when invoked:
- a function
- references:
- notes:
createReduxSelector()
can be called outside of a React component's render function- however, the function it creates must only be called inside of a React component's render function
- same as the default behavior for
require('reselect').createSelector
- reference equality (
===
) is the default behavior used to determine if the value returned by an input-selector has changed between calls
- reference equality (
- though one or more
inputSelectors
should be considered required- the fallback behavior when none are providedis to create a function that is roughly equivalent to:
(...ignored) => useReduxMappedState(resultFunc)
- the fallback behavior when none are providedis to create a function that is roughly equivalent to:
- efficiency considerations:
- on 1st render of React component:
- all
inputSelectors
execute resultFunc
executes
- all
- on subsequent renders of React component:
- all
inputSelectors
are memoized- cache of each corresponding result value is invalidated under any of the following circumstances:
- global Redux
state
is changed - one or more values in the list of input parameters is changed
- global Redux
- cache of each corresponding result value is invalidated under any of the following circumstances:
resultFunc
is memoized- cache of the result value is invalidated when:
- one or more values in the list of input parameters is changed
- this list of input parameters is the ordered list of output values as produced by the
inputSelectors
- how change is determined can be configured in options
- by default, equality is determined by reference
- when
options.equality.recalculate === 'shallow'
, equality is also determined by reference.. such that:- top-level Objects and Arrays do not need to be equal by reference
- top-level Objects and Arrays must contain children that are all equal by reference
- when
options.equality.recalculate === 'deep'
, equality is determined.. such that:- Objects and Arrays at any depth within the data structure do not need to be equal by reference
- Objects and Arrays at any depth within the data structure must contain children that are either:
- an Object or Array
- a data type that can be converted to a primitive value and compared for equality
- this list of input parameters is the ordered list of output values as produced by the
- one or more values in the list of input parameters is changed
- cache of the result value is invalidated when:
- all
- on 1st render of React component:
- examples:
- input:
StoreContext
- type:
- React context
- ie: as output by
React.createContext()
- ie: as output by
- React context
- note:
- alias for:
require('redux-react-hook').StoreContext
- alias for:
- type:
Demos:
- very basic example
- design
- Redux state stores 'todos'
- React state stores 'theme'
- the reducer's dispatch is added to the unified dispatcher
- the unified dispatcher is called by a different component to mutate the state of the component that owns the reducer
- implementations
- design
Tests:
- unit tests that run in Browser Mocha
References:
Docs:
Video:
Legal:
- copyright: Warren Bank
- license: GPL-2.0