![Oracle Drags Its Feet in the JavaScript Trademark Dispute](https://cdn.sanity.io/images/cgdhsj6q/production/919c3b22c24f93884c548d60cbb338e819ff2435-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
redux-compose
Advanced tools
Higher Order functions to aid in composing Redux Reducers.
While redux provides a clean separation of concerns by distinguishing actions and reducers the examples
given don't provide a lot of examples on how to break down complex reducers into distinct and testable
components. The provided combineReducers
can act as a starting point but doesn't scale
up to lots of reducer logic.
This library exports a set of higher order functions that allow you to write very focused reducers and compose them into a single larger complex reducer. Additionally by leveraging these helper functions we're able to gain large amounts of type inference in order to reduce some of the typing overhead with Redux
npm add --save redux-compose
yarn add redux-compose
All functions are exported as a ESModule from the index file, or as ESModules from independent files.
// either
import { composeReducers } from 'redux-compose';
// or
import { composeReducers } from 'redux-compose/compose-reducers';
composeReducers(...reducers)
Given a set of reducers returns a reducer. When invoked each of the given reducers are called in order with the action and the state that is returned from the previous reducer.
composeReducers
is the primary composition function, and should be the main means of combining specific reducers
to form a larger reducer. Other functions provide a set of action and state filtering operations.
The reducers are called in left-to-right order so the 2 pieces of code are equivalent:
import { composeReducers } from 'redux-compose/compose-reducers';
...
export const reducer = composeReducers<State>(
reducer1,
reducer2,
reducer3
);
...
export const reducer = (state: State, action: AnyAction) => (
reducer3(
reducer2(
reducer1(state, action),
action
),
action
)
)
forPath([...pathPart|pathPartFunction], subStateReducer)
forPath
creates a reducer that targets a sub section of the state. The first
argument is a path expressed as an array of string, numbers, or functions that translate
an action into a string or number. The second argument is a reducer that will be
called with the state at the given path.
forPath
will try to create intermediary states if the path crosses an
undefined value. If the path part is a number the intermediary state will be a
empty array, otherwise it will be a empty object.
When updating values in an array forPath
may create a sparse array.
Example:
import { forPath } from 'redux-compose/for-path';
interface State {
foo: {
bar: Array<{
baz: number;
}>;
};
}
interface AddOneAction {
type: 'AddOne';
payload: {
index: number;
};
}
export const addOne = forPath(
// path into the state, the index into the array of
// bar is derived from the payload of the action
['foo', 'bar', ({ payload: { index } }: AddOneAction) => index, 'baz'],
(state: number) => state + 1
);
ofType(typeString|typePredicate|[...typeString|typePredicate], reducer)
Given a typeString or typePredicate, or array of typeStrings or typePredicates and a reducer return a reducer that is only invoked when the action matches one of the types.
If the type is provided as a string the string is used to match the type field on the action. If the type is provided as a function the action is passed to the function.
To match on multiple types an array of either strings or functions can be provided, in which case they act as an "or" match on the action.
Example:
import { ofType } from 'redux-compose/of-type';
const INCREMENT: 'Increment' = 'Increment';
const DECREMENT: 'Decrement' = 'Decrement';
export const incrementReducer = ofType(
// only invoked with the increment type
INCREMENT,
state => state + 1
);
export const decrementReducer = ofType(
// using a type predicate
({ type }) => type === DECREMENT,
state => state - 1
);
// specify multiple type strings or predicates to handle
// multiple actions
export const bothReducer = ofType([INCREMENT, ({ type }) => type === DECREMENT], (state, action) =>
incrementReducer(decrementReducer(state, action), action)
);
withDefault(defaultState, reducer?)
Given a default state and a reducer returns a reducer which invokes the provided reducer
using the default state if the state is undefined
.
Example:
import { withDefault } from 'redux-compose/with-default';
interface State {
value: number;
}
const reducer = withDefault<State>({ value: 2 }, (state, action) => {
switch (action.type) {
case 'Increment':
return {
...state,
value: state.value + 1
};
default:
return state;
}
});
/*
reducer will use { value: 2 } as the default state,
reducer(undefined, { type: 'Increment' }) === 3
*/
If no reducer argument is provided to withDefault
then a identity reducer (state => state
) is used.
This is useful when paired with composeReducers
to set an initial state for a series of reducers.
import { composeReducers } from 'redux-compose/compose-reducers';
import { withDefault } from 'redux-compose/with-default';
interface State {
value: number;
}
const reducer = composeReducers<State>(
withDefault({ value: 2 })
// other reducers can now depend on
// state not being undefined.
);
We use yarn and nvm to ensure consistent build environments.
yarn test
yarn gulp
yarn format
yarn lint
While all contributes are welcome the following rules will help you get your contributes accepted faster:
MIT
FAQs
Higher Order functions to aid in composing Redux Reducers
The npm package redux-compose receives a total of 37 weekly downloads. As such, redux-compose popularity was classified as not popular.
We found that redux-compose demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.