UNPKG

@wordpress/data

Version:
53 lines (49 loc) 1.41 kB
/** * External dependencies */ import type { AnyAction, Reducer } from 'redux'; /** * Higher-order reducer creator which creates a combined reducer object, keyed * by a property on the action object. * * @param actionProperty Action property by which to key object. * @return Higher-order reducer. * * @example * ```js * import { keyedReducer } from '@wordpress/data'; * * const itemsByContext = keyedReducer( 'context' )( ( state = [], action ) => { * switch ( action.type ) { * case 'ADD_ITEM': * return [ ...state, action.item ]; * } * return state; * } ); * ``` */ export const keyedReducer = < TState extends unknown, TAction extends AnyAction >( actionProperty: string ) => ( reducer: Reducer< TState, TAction > ): Reducer< Record< string, TState >, TAction > => ( state: Record< string, TState > = {}, action ) => { // Retrieve subkey from action. Do not track if undefined; useful for cases // where reducer is scoped by action shape. const key = action[ actionProperty ]; if ( key === undefined ) { return state; } // Avoid updating state if unchanged. Note that this also accounts for a // reducer which returns undefined on a key which is not yet tracked. const nextKeyState = reducer( state[ key ], action ); if ( nextKeyState === state[ key ] ) { return state; } return { ...state, [ key ]: nextKeyState, }; };