Acabo de descubrir que puedo usar ganchos de datos en las funciones createSelector y funciona. Un ejemplo:
// This is a normal hook const useUserReducer = () => { const userAccessData = useSelector(state => state?.userAccessData) return userAccessData } // Here I use the hook as first argument! export const useUserReducerFromCreateSelector = createSelector(useUserReducer, (result) => { console.log(result) // userAccessData printed correctly return result })Luego lo uso en mi componente como un gancho normal:
const Component = () => { const result = useUserReducerFromCreateSelector([]) console.log(result) // userAccessData printed correctly return ( <> {JSON.stringify(result)} </> ) }No veo ninguna documentación sobre esto, así que me pregunto si es seguro usarlo. Me ayudaría mucho crear selectores reutilizables.
(Probé mientras cambiaba el estado en varios momentos y siempre veo el estado correcto)
Sin duda es un abuso si está funcionando. Se supone que createSelector solo es una función selectora de estado puro, por lo que nombrar la función selectora devuelta como un enlace de React, es decir, useUserReducerFromCreateSelector , es probable que eventualmente cause algunas advertencias de linter.
El problema potencial es que Reselect y createSelector crean funciones de selector memorizadas. Si el valor de entrada de un selector no cambia, la función de selector devuelve el valor de selector calculado previamente. Esto significa que un selector que usa un gancho de React como este puede llamar condicionalmente a un gancho de React, lo que es una violación de las Reglas de Hooks.
Solo ganchos de llamada en el nivel superior
No llame a Hooks dentro de bucles, condiciones o funciones anidadas. En su lugar, siempre use Hooks en el nivel superior de su función React, antes de cualquier retorno anticipado. Al seguir esta regla, te aseguras de que los ganchos se llamen en el mismo orden cada vez que se represente un componente. Eso es lo que le permite a React preservar correctamente el estado de los Hooks entre múltiples llamadas
useStateyuseEffect. (Si tiene curiosidad, lo explicaremos en profundidad a continuación).Solo ganchos de llamada desde funciones de reacción
Don't call Hooks from regular JavaScript functions.En su lugar, puede:
- ✅ Call Hooks de los componentes de la función React.
- ✅ Call Hooks desde Hooks personalizados (aprenderemos sobre ellos en la página siguiente).
Al seguir esta regla, se asegura de que toda la lógica con estado en un componente sea claramente visible desde su código fuente.
No considero seguro usar ningún gancho React en una función de selector como esta.
Divida la lógica de seleccionar el estado del useUserReducerFromCreateSelector para usar en sus funciones de selector.
Ejemplo:
const userAccessData = state => state?.userAccessData || {}; const computedUserAccessData = createSelector( [userAccessData], data => { // logic to compute derived state, etc... return newUserAccessData; }, );Estaba realmente intrigado al ver este uso particular en los problemas del repositorio de github redux-toolkit y nadie se quejaba de eso, así que decidí hacer la misma pregunta en la página de reselect para volver a seleccionar.
Aquí está la respuesta de Mark Erikson (mantenedor de redux):
¡No, esto no es seguro!
Técnicamente, se está saliendo con la suya debido a cómo lo está usando en un componente. Pero si intentara usar ese selector fuera de un componente, se rompería.
Realmente recomendaría mantener estos conceptos separados. Escribir y nombrar selectores como selectores. Escribir y nombrar ganchos como ganchos. No intentes mezclar los dos :)
Para que quede claro, el código que escribiste arriba debería ejecutarse. En última instancia, es "solo" la composición de funciones y llamarlas en un orden particular.
Pero dado cómo funcionan los ganchos y los selectores, es mejor mantener esos conceptos separados al escribir el código para evitar confusiones.