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,
|
baseSelector: any,
|
||||||
locationString: string,
|
locationString: string,
|
||||||
} = {}): PartialReducer {
|
} = {}): 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 }`);
|
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,
|
//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
|
//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.
|
//returned to the call site for use in the rest of the application.
|
||||||
const temp = reduce(structure, processStructure, {
|
const temp = reduce(structure, processStructure, {
|
||||||
reducers: {},
|
reducers: {
|
||||||
|
[name]: {},
|
||||||
|
},
|
||||||
actions: {},
|
actions: {},
|
||||||
selectors: {},
|
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.
|
//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
|
//This helper, if you're not aware, ensures that the correct store properties are passed to the
|
||||||
//reducers assigned to those properties.
|
//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) {
|
function processStructure(memo: PartialReducer, propValue: StructureType | PrimitiveType, propName: string) {
|
||||||
//Get the structure from the propValue. In the case of 'StructureType' properties, this
|
//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
|
//createReducer function, which will create the correct reducer for the given structure
|
||||||
//(which can be either object, array, or primitive).
|
//(which can be either object, array, or primitive).
|
||||||
let childReducer = containsReducers
|
let childReducer = containsReducers
|
||||||
? reducerBuilder(propName, propStructure, {
|
? buildReducer(propName, propStructure, {
|
||||||
locationString: locationString ? `${locationString}.${propName}` : propName,
|
locationString: locationString ? `${locationString}.${propName}` : propName,
|
||||||
baseSelector: (state: any) => baseSelector(state)[propName],
|
baseSelector: (state: any) => baseSelector(state)[propName],
|
||||||
})
|
})
|
||||||
: createReducer(propValue, {
|
: createReducer(propValue, {
|
||||||
locationString: `${locationString}.${propName}`,
|
locationString: `${locationString}.${propName}`,
|
||||||
|
name: propName,
|
||||||
});
|
});
|
||||||
|
|
||||||
//As the object is built up, we want to assign the reducers/actions created
|
//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
|
//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
|
//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.
|
//need to know where it is located within the grand scheme of things.
|
||||||
|
|
||||||
return {
|
return {
|
||||||
reducers: {
|
reducers: {
|
||||||
...memo.reducers,
|
...memo.reducers,
|
||||||
[propName]: childReducer.reducers,
|
...childReducer.reducers
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
...memo.actions,
|
...memo.actions,
|
||||||
|
|
|
@ -29,6 +29,7 @@ import { createPrimitiveReducer } from './reducers/primitiveReducer';
|
||||||
|
|
||||||
|
|
||||||
function determineReducerType(reducerDescriptor, {
|
function determineReducerType(reducerDescriptor, {
|
||||||
|
name,
|
||||||
locationString,
|
locationString,
|
||||||
}) {
|
}) {
|
||||||
const REDUCERS = {
|
const REDUCERS = {
|
||||||
|
@ -42,15 +43,17 @@ function determineReducerType(reducerDescriptor, {
|
||||||
const { type } = structure();
|
const { type } = structure();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
name,
|
||||||
reducerFn: REDUCERS[type],
|
reducerFn: REDUCERS[type],
|
||||||
reducerStructureDescriptor: structure,
|
reducerStructureDescriptor: structure,
|
||||||
locationString,
|
locationString,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function callReducer({ reducerFn, reducerStructureDescriptor, locationString } = {}) {
|
function callReducer({ name, reducerFn, reducerStructureDescriptor, locationString } = {}) {
|
||||||
return reducerFn(reducerStructureDescriptor, {
|
return reducerFn(reducerStructureDescriptor, {
|
||||||
locationString,
|
locationString,
|
||||||
|
name,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ export type ArrayActions = {
|
||||||
export type ArrayReducerOptions = {
|
export type ArrayReducerOptions = {
|
||||||
behaviorsConfig: ArrayReducerBehaviorsConfig,
|
behaviorsConfig: ArrayReducerBehaviorsConfig,
|
||||||
locationString: string,
|
locationString: string,
|
||||||
|
name: string,
|
||||||
};
|
};
|
||||||
export type ArraySelector = (state: Object) => Array<any>;
|
export type ArraySelector = (state: Object) => Array<any>;
|
||||||
|
|
||||||
|
@ -96,10 +97,13 @@ const DEFAULT_ARRAY_BEHAVIORS: ArrayReducerBehaviorsConfig = {
|
||||||
|
|
||||||
|
|
||||||
export function createArrayReducer(arrayTypeDescription: ArrayStructureType, {
|
export function createArrayReducer(arrayTypeDescription: ArrayStructureType, {
|
||||||
locationString
|
locationString,
|
||||||
|
name,
|
||||||
}: ArrayReducerOptions = {}) {
|
}: ArrayReducerOptions = {}) {
|
||||||
return {
|
return {
|
||||||
reducers: createReducer(arrayTypeDescription, createReducerBehaviors(DEFAULT_ARRAY_BEHAVIORS, locationString)),
|
reducers: {
|
||||||
|
[name]: createReducer(arrayTypeDescription, createReducerBehaviors(DEFAULT_ARRAY_BEHAVIORS, locationString))
|
||||||
|
},
|
||||||
actions: createActions(DEFAULT_ARRAY_BEHAVIORS, locationString, {}),
|
actions: createActions(DEFAULT_ARRAY_BEHAVIORS, locationString, {}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ export type ObjectActions = {
|
||||||
export type ObjectReducerOptions = {
|
export type ObjectReducerOptions = {
|
||||||
behaviorsConfig: ObjectReducerBehaviorsConfig,
|
behaviorsConfig: ObjectReducerBehaviorsConfig,
|
||||||
locationString: string,
|
locationString: string,
|
||||||
|
name: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
//==============================
|
//==============================
|
||||||
|
@ -60,10 +61,13 @@ const DEFAULT_OBJECT_BEHAVIORS: ObjectReducerBehaviorsConfig = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export function createObjectReducer(reducerShape: StructureType, {
|
export function createObjectReducer(reducerShape: StructureType, {
|
||||||
locationString
|
locationString,
|
||||||
|
name,
|
||||||
}: ObjectReducerOptions = {}) {
|
}: ObjectReducerOptions = {}) {
|
||||||
return {
|
return {
|
||||||
reducers: createReducer(reducerShape, createReducerBehaviors(DEFAULT_OBJECT_BEHAVIORS, locationString)),
|
reducers: {
|
||||||
|
[name]: createReducer(reducerShape, createReducerBehaviors(DEFAULT_OBJECT_BEHAVIORS, locationString)),
|
||||||
|
},
|
||||||
actions: createActions(DEFAULT_OBJECT_BEHAVIORS, locationString, {}),
|
actions: createActions(DEFAULT_OBJECT_BEHAVIORS, locationString, {}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ export type PrimitiveActions = {
|
||||||
export type PrimitiveReducerOptions = {
|
export type PrimitiveReducerOptions = {
|
||||||
behaviorsConfig: PrimitiveReducerBehaviorsConfig,
|
behaviorsConfig: PrimitiveReducerBehaviorsConfig,
|
||||||
locationString: string,
|
locationString: string,
|
||||||
|
name: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
//==============================
|
//==============================
|
||||||
|
@ -55,10 +56,13 @@ const DEFAULT_PRIMITIVE_BEHAVIORS: PrimitiveReducerBehaviorsConfig = {
|
||||||
|
|
||||||
|
|
||||||
export function createPrimitiveReducer(primitiveType: PrimitiveType, {
|
export function createPrimitiveReducer(primitiveType: PrimitiveType, {
|
||||||
locationString
|
locationString,
|
||||||
|
name,
|
||||||
}: PrimitiveReducerOptions = {}) {
|
}: PrimitiveReducerOptions = {}) {
|
||||||
return {
|
return {
|
||||||
reducers: createReducer(primitiveType, createReducerBehaviors(DEFAULT_PRIMITIVE_BEHAVIORS, locationString)),
|
reducers: {
|
||||||
|
[name]: createReducer(primitiveType, createReducerBehaviors(DEFAULT_PRIMITIVE_BEHAVIORS, locationString)),
|
||||||
|
},
|
||||||
actions: createActions(DEFAULT_PRIMITIVE_BEHAVIORS, locationString, {}),
|
actions: createActions(DEFAULT_PRIMITIVE_BEHAVIORS, locationString, {}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue