Selectores NGRX: selector de fábrica dentro de otro selector sin prop en el método createSelector.
Usando el patrón de selector de fábrica const selectA = (id: número) => createSelector (...)
, tengo una instancia donde quiero reutilizar este selector dentro de otro selector (que itera a través de una matriz de identificadores) pero no sé el valor a pasar al selector de fábrica al llamar a createSelector
.
Entonces tengo un selector que uso siempre que quiero obtener una porción del estado para el componente A.
const selectA = (id: número) =>
createSelector (
selector1.selectEntityMap,
selector2.selectEntityMap,
selector3ById(id),
(
thing1,
thing2,
thing3
) => {
return ...
});
Ahora quiero obtener una lista del componente A para cada elemento en una matriz.
const selectListOfA = (ids: número[]) =>
createSelector (
selectA,
(selectorA) => {
return ids.map((id) => selectorA(id));
});
El problema es selectA
, que ahora es un selector de fábrica, espera un parámetro, pero no lo sé al llamar a createSelector
.
Puedo hacer que el código se compile creando otra fábrica sobre la fábrica
const selectAFactory = () => selectA;
Y luego haga referencia a la nueva fábrica en el createSelector
const selectListOfA = (ids: número[]) =>
createSelector (
selectAFactory, <<< aquí
(selectorA) => {
return ids.map((id) => selectorA(id));
});
Pero, por supuesto, lo que está sucediendo ahora es que el selector devuelve una lista de MemoizedSelector []
.
Este patrón no parece que debería ser tan complicado, ¿la gente no está reutilizando sus selectores de esta manera, qué me estoy perdiendo?
davy.ai
Es posible reutilizar un selector de fábrica dentro de otro selector que itera a través de una matriz de IDs. El problema con la implementación actual es que el selector de fábrica
selectA
espera un parámetro de ID al llamar acreateSelector
, pero este ID es desconocido al crear el selectorselectListOfA
.Una solución es crear otra fábrica sobre la fábrica
selectA
, como esta:Entonces, hacer referencia a la nueva fábrica en el
createSelector
deselectListOfA
:Sin embargo, esto devolverá una lista de
MemoizedSelector []
, ya que cada invocación deselectorA
devuelve una nueva función de selector.Para solucionar esto, podemos modificar el selector
selectListOfA
para pasar el parámetro de ID a la fábrica del selectorselectA
para cada iteración:Ahora,
selectListOfA
devolverá correctamente una lista de funcionesMemoizedSelector
que cada una toma un estado de entidad como entrada y devuelve la porción de estado para el componente A.En resumen, el uso de un patrón de selector de fábrica para reutilizar selectores puede ser complejo cuando el selector externo necesita pasar parámetros al selector interno. En este caso, podemos crear una nueva fábrica sobre la original para diferir el parámetro de ID hasta más tarde. Luego podemos modificar el selector externo para recibir el parámetro de ID como prop, llamar a la nueva fábrica con el ID y usar la función de selector resultante para cada iteración de la matriz.