Update reducer recursion to improve output structure
This commit is contained in:
parent
b5e6f9024c
commit
966b7739bf
|
@ -18,32 +18,15 @@ export function buildReducer(name: string, structure: any, {
|
|||
baseSelector: any,
|
||||
locationString: string,
|
||||
} = {}): PartialReducer {
|
||||
const temp = reducerBuilder(name, structure, {
|
||||
baseSelector,
|
||||
locationString
|
||||
});
|
||||
return {
|
||||
...temp,
|
||||
reducers: {
|
||||
[name]: temp.reducers,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function reducerBuilder(name: string, structure: any, {
|
||||
baseSelector = state => state[name],
|
||||
locationString = '',
|
||||
}: {
|
||||
baseSelector: any,
|
||||
locationString: string,
|
||||
} = {}): PartialReducer {
|
||||
|
||||
if (structure === undefined) throw new Error(`The structure must be defined for a reducer! LocationString: ${ locationString }`);
|
||||
//Build up the reducers, actions, and selectors for this level. Due to recursion,
|
||||
//these objects will be assigned to a property in the parent object, or simply
|
||||
//returned to the call site for use in the rest of the application.
|
||||
const temp = reduce(structure, processStructure, {
|
||||
reducers: {},
|
||||
reducers: {
|
||||
[name]: {},
|
||||
},
|
||||
actions: {},
|
||||
selectors: {},
|
||||
});
|
||||
|
@ -51,7 +34,9 @@ function reducerBuilder(name: string, structure: any, {
|
|||
//The Redux 'combineReducers' helper function is used here to save a little bit of boilerplate.
|
||||
//This helper, if you're not aware, ensures that the correct store properties are passed to the
|
||||
//reducers assigned to those properties.
|
||||
return { ...temp, reducers: combineReducers(temp.reducers) };
|
||||
return { ...temp, reducers: {
|
||||
[name]: combineReducers(temp.reducers)
|
||||
}};
|
||||
|
||||
function processStructure(memo: PartialReducer, propValue: StructureType | PrimitiveType, propName: string) {
|
||||
//Get the structure from the propValue. In the case of 'StructureType' properties, this
|
||||
|
@ -66,22 +51,24 @@ function reducerBuilder(name: string, structure: any, {
|
|||
//createReducer function, which will create the correct reducer for the given structure
|
||||
//(which can be either object, array, or primitive).
|
||||
let childReducer = containsReducers
|
||||
? reducerBuilder(propName, propStructure, {
|
||||
? buildReducer(propName, propStructure, {
|
||||
locationString: locationString ? `${locationString}.${propName}` : propName,
|
||||
baseSelector: (state: any) => baseSelector(state)[propName],
|
||||
})
|
||||
: createReducer(propValue, {
|
||||
locationString: `${locationString}.${propName}`,
|
||||
name: propName,
|
||||
});
|
||||
|
||||
//As the object is built up, we want to assign the reducers/actions created
|
||||
//by the child to a location on the reducers/actions object which will match up
|
||||
//to their location. Selectors are created at this level, as the child does not
|
||||
//need to know where it is located within the grand scheme of things.
|
||||
|
||||
return {
|
||||
reducers: {
|
||||
...memo.reducers,
|
||||
[propName]: childReducer.reducers,
|
||||
...childReducer.reducers
|
||||
},
|
||||
actions: {
|
||||
...memo.actions,
|
||||
|
|
|
@ -29,6 +29,7 @@ import { createPrimitiveReducer } from './reducers/primitiveReducer';
|
|||
|
||||
|
||||
function determineReducerType(reducerDescriptor, {
|
||||
name,
|
||||
locationString,
|
||||
}) {
|
||||
const REDUCERS = {
|
||||
|
@ -42,15 +43,17 @@ function determineReducerType(reducerDescriptor, {
|
|||
const { type } = structure();
|
||||
|
||||
return {
|
||||
name,
|
||||
reducerFn: REDUCERS[type],
|
||||
reducerStructureDescriptor: structure,
|
||||
locationString,
|
||||
};
|
||||
}
|
||||
|
||||
function callReducer({ reducerFn, reducerStructureDescriptor, locationString } = {}) {
|
||||
function callReducer({ name, reducerFn, reducerStructureDescriptor, locationString } = {}) {
|
||||
return reducerFn(reducerStructureDescriptor, {
|
||||
locationString,
|
||||
name,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ export type ArrayActions = {
|
|||
export type ArrayReducerOptions = {
|
||||
behaviorsConfig: ArrayReducerBehaviorsConfig,
|
||||
locationString: string,
|
||||
name: string,
|
||||
};
|
||||
export type ArraySelector = (state: Object) => Array<any>;
|
||||
|
||||
|
@ -96,10 +97,13 @@ const DEFAULT_ARRAY_BEHAVIORS: ArrayReducerBehaviorsConfig = {
|
|||
|
||||
|
||||
export function createArrayReducer(arrayTypeDescription: ArrayStructureType, {
|
||||
locationString
|
||||
locationString,
|
||||
name,
|
||||
}: ArrayReducerOptions = {}) {
|
||||
return {
|
||||
reducers: createReducer(arrayTypeDescription, createReducerBehaviors(DEFAULT_ARRAY_BEHAVIORS, locationString)),
|
||||
reducers: {
|
||||
[name]: createReducer(arrayTypeDescription, createReducerBehaviors(DEFAULT_ARRAY_BEHAVIORS, locationString))
|
||||
},
|
||||
actions: createActions(DEFAULT_ARRAY_BEHAVIORS, locationString, {}),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ export type ObjectActions = {
|
|||
export type ObjectReducerOptions = {
|
||||
behaviorsConfig: ObjectReducerBehaviorsConfig,
|
||||
locationString: string,
|
||||
name: string,
|
||||
};
|
||||
|
||||
//==============================
|
||||
|
@ -60,10 +61,13 @@ const DEFAULT_OBJECT_BEHAVIORS: ObjectReducerBehaviorsConfig = {
|
|||
};
|
||||
|
||||
export function createObjectReducer(reducerShape: StructureType, {
|
||||
locationString
|
||||
locationString,
|
||||
name,
|
||||
}: ObjectReducerOptions = {}) {
|
||||
return {
|
||||
reducers: createReducer(reducerShape, createReducerBehaviors(DEFAULT_OBJECT_BEHAVIORS, locationString)),
|
||||
reducers: {
|
||||
[name]: createReducer(reducerShape, createReducerBehaviors(DEFAULT_OBJECT_BEHAVIORS, locationString)),
|
||||
},
|
||||
actions: createActions(DEFAULT_OBJECT_BEHAVIORS, locationString, {}),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ export type PrimitiveActions = {
|
|||
export type PrimitiveReducerOptions = {
|
||||
behaviorsConfig: PrimitiveReducerBehaviorsConfig,
|
||||
locationString: string,
|
||||
name: string,
|
||||
};
|
||||
|
||||
//==============================
|
||||
|
@ -55,10 +56,13 @@ const DEFAULT_PRIMITIVE_BEHAVIORS: PrimitiveReducerBehaviorsConfig = {
|
|||
|
||||
|
||||
export function createPrimitiveReducer(primitiveType: PrimitiveType, {
|
||||
locationString
|
||||
locationString,
|
||||
name,
|
||||
}: PrimitiveReducerOptions = {}) {
|
||||
return {
|
||||
reducers: createReducer(primitiveType, createReducerBehaviors(DEFAULT_PRIMITIVE_BEHAVIORS, locationString)),
|
||||
reducers: {
|
||||
[name]: createReducer(primitiveType, createReducerBehaviors(DEFAULT_PRIMITIVE_BEHAVIORS, locationString)),
|
||||
},
|
||||
actions: createActions(DEFAULT_PRIMITIVE_BEHAVIORS, locationString, {}),
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue