He estado probando React Hooks y parecen simplificar cosas como el estado de almacenamiento. Sin embargo, parecen hacer muchas cosas por arte de magia y no puedo encontrar un buen artículo sobre cómo funcionan realmente.
Lo primero que parece ser mágico es cómo llamar a una función como useState() provoca una nueva representación de su componente funcional cada vez que llama al método setXXX que devuelve.
¿Cómo algo como useEffect() falsifica un componenteDidMount cuando los componentes funcionales ni siquiera tienen la capacidad de ejecutar código en Mount/Unmount?
¿Cómo utiliza useContext() realmente el acceso al contexto y cómo sabe qué componente lo está llamando?
Y eso ni siquiera comienza a cubrir todos los ganchos de terceros que ya están surgiendo como useDataLoader que le permite usar lo siguiente...
const { data, error, loading, retry } = useDataLoader(getData, id)¿Cómo los datos, el error, la carga y el reintento vuelven a renderizar su componente cuando cambian?
Lo siento, muchas preguntas, pero supongo que la mayoría de ellas se pueden resumir en una pregunta, que es:
¿Cómo obtiene acceso la función detrás del gancho al componente funcional/sin estado que lo está llamando para que pueda recordar cosas entre renderizaciones e iniciar una nueva renderización con nuevos datos?
React hook hace uso del estado oculto de un componente, se almacena dentro de una fibra , una fibra es una entidad que corresponde a la instancia del componente (en un sentido más amplio, porque los componentes funcionales no crean instancias como componentes de clase).
Es el renderizador de React el que da acceso a un gancho al contexto respectivo, estado, etc. y, por cierto, es el renderizador de React que llama a la función del componente. Por lo tanto, puede asociar la instancia del componente con funciones de enlace que se llaman dentro de la función del componente.
Este fragmento explica cómo funciona:
let currentlyRenderedCompInstance; const compStates = new Map(); // maps component instances to their states const compInstances = new Map(); // maps component functions to instances function useState(initialState) { if (!compStates.has(currentlyRenderedCompInstance)) compStates.set(currentlyRenderedCompInstance, initialState); return [ compStates.get(currentlyRenderedCompInstance) // state val => compStates.set(currentlyRenderedCompInstance, val) // state setter ]; } function render(comp, props) { const compInstanceToken = Symbol('Renderer token for ' + comp.name); if (!compInstances.has(comp)) compInstances.set(comp, new Set()); compInstances.get(comp).add(compInstanceToken); currentlyRenderedCompInstance = compInstanceToken; return { instance: compInstanceToken, children: comp(props) }; } De manera similar a cómo useState puede acceder al token de la instancia del componente representado currentlyRenderedCompInstance a través de currentRenderedCompInstance , otros ganchos integrados también pueden hacer esto y mantener el estado de esta instancia del componente.
Dan Abramov creó una publicación de blog hace solo un par de días que cubre esto:
https://overreacted.io/how-does-setstate-snow-what-to-do/
La segunda mitad entra específicamente en detalles sobre ganchos como useState.
Para aquellos interesados en profundizar en algunos de los detalles de implementación, aquí tengo una respuesta relacionada: ¿Cómo determinan los ganchos de reacción el componente para el que son?
Recomendaría leer https://eliav2.github.io/how-react-hooks-work/
Incluye explicaciones detalladas sobre lo que sucede cuando se usan ganchos de reacción y lo demuestra con muchos ejemplos interactivos.
Nota: el artículo no explica en términos técnicos cómo la programación de React solicita las fases posteriores, sino que demuestra cuáles son las reglas que utiliza React para programar las llamadas de las fases posteriores.