Fiber y el double buffering
¿Dónde guarda React el estado si los componentes son funciones sin memoria?
Al terminar vas a poder explicar
- Describir qué campos tiene un fiber y para qué sirve cada uno
- Explicar qué significa el puntero alternate
- Decir en qué momento exacto el árbol workInProgress pasa a ser el actual
Tenemos un problema. Tu componente es una función que se ejecuta de arriba a abajo y termina. Cuando vuelve a ejecutarse, todas sus variables locales son nuevas. No tiene memoria. Y sin embargo useState se acuerda del valor anterior.
La respuesta es que el estado nunca estuvo en tu función. Está al lado, en una estructura que React mantiene en paralelo al árbol de componentes: el árbol de fibers.
Qué es un fiber
Un fiber es un objeto plano que representa una aparición concreta de un componente. Si renderizás <Fila /> tres veces, hay tres fibers, cada uno con su propio estado. Estos son los campos que importan:
1{2 tag: "FunctionComponent", // qué clase de nodo es3 type: Fila, // la función, o "div" si es un host4 key: "alfa", // la identidad que le diste vos5 6 pendingProps: { ... }, // las props de este render7 memoizedProps: { ... }, // las del render anterior8 memoizedState: hook0, // ← acá cuelga la cadena de hooks9 10 return: fiberPadre, // hacia arriba11 child: primerHijo, // hacia abajo12 sibling: siguienteHermano, // hacia el costado13 14 alternate: fiberGemelo, // el otro buffer15 flags: 0b000001, // qué hacer en el commit16 lanes: 0b010, // qué prioridad tiene el trabajo pendiente17 stateNode: nodoDelDOM // sólo en componentes host18}El árbol no es un árbol de arrays
Mirá los punteros: child, sibling, return. Un fiber no tiene un array de hijos. Tiene un hijo, y ese hijo tiene un hermano, que tiene otro hermano. Es una lista enlazada dentro de un árbol.
Esto no es capricho. Con un array, recorrer el árbol requiere recursión — y una recursión no se puede pausar a la mitad sin perder el stack. Con punteros, React puede guardar un solo cursor («estaba en este fiber»), soltar el hilo para que el navegador atienda un click, y retomar exactamente donde estaba.
El double buffering
Acá viene la parte que casi nadie tiene clara. React no tiene un árbol: tiene dos, y los va alternando.
- current — el árbol que está en pantalla ahora mismo.
- workInProgress — el que React está construyendo, en memoria, invisible.
Cada fiber apunta a su gemelo del otro árbol con alternate. Cuando React termina de construir el workInProgress, hace una sola asignación — root.current = finishedWork — y el árbol nuevo pasa a ser el actual. El viejo no se tira: queda libre para reciclarse en el próximo render.
Es la misma técnica que usan los motores gráficos: dibujás en un buffer oculto y recién después lo mostrás entero. Nadie ve un cuadro a medio dibujar.
Mirá cuándo aparece el buffer alterno, y cuándo se intercambian
AGENDADOpaso 1 / 96Sin hooks en este paso.
Árbol de fibers
- <HostRoot>
Salida
Nada en el host todavía. React no commiteó ningún cambio.
createRoot().render()
Montaje inicial. No hay árbol previo, así que todo se va a crear desde cero.
VER EL CÓDIGO QUE SE ESTÁ TRAZANDO
1function Contador() {2 const [n, setN] = useState(0);3 4 return (5 <div>6 <p>Valor: {n}</p>7 <button onClick={() => setN(n + 1)}>sumar 1</button>8 </div>9 );10}Con el foco acá: ← → un paso · espacio reproduce · Inicio/Fin van a los extremos.
Fijate en dos momentos de esa traza. En el montaje aparece createWorkInProgress diciendo que no existía buffer alterno — porque es la primera vez. En el segundo render, el mismo paso dice que lo reutiliza. Ahí está el reciclado: React deja de asignar objetos nuevos y alterna entre dos.
Y al final de cada ciclo vas a ver root.current = finishedWork. Ese es el instante del intercambio. Un puntero. Nada más.
Antes de seguir · predecí
Durante la fase de render, mientras React construye el workInProgress, ¿qué se está viendo en la pantalla?
Lo que te llevás
Tu estado vive en fiber.memoizedState, no en tu función. El árbol se recorre con punteros para poder pausarse. Y hay dos árboles alternándose, lo que permite construir en privado y publicar de golpe. En la próxima lección vamos a ver esas dos etapas — construir y publicar — con nombre y apellido.
Antes de marcarla, comprobá
- ¿Podés explicar describir qué campos tiene un fiber y para qué sirve cada uno?
- ¿Podés explicar explicar qué significa el puntero alternate?
- ¿Podés explicar decir en qué momento exacto el árbol workInProgress pasa a ser el actual?