Hook useEffect se ejecuta de forma asíncrona y, por lo general, después de que el DOM se renderiza/monta, mientras que useLayoutEffect se ejecuta de forma síncrona y antes de que el DOM se renderice/monte.
Usando mi ejemplo useEffect, todo funciona bien y obtengo el resultado deseado (almaceno el valor anterior que el usuario ingresó usando useRef).
Pero usando mi ejemplo useLayoutEffect, no obtengo el resultado deseado, porque solo funciona como useEffect en mi caso. Considero que primero debería actualizar prevName.current = name y solo después de renderizar causando el mismo valor que la persona ha ingresado. Creo que, en ese caso, tanto prevName.current como name deberían representarse como los mismos valores. Pero eso no sucede.
¿Puedes explicar por qué?
Aquí está codesandbox: Sandbox
Aquí está el código:
import React, { useLayoutEffect } from "react"; import "./styles.css"; import { useState, useRef, useEffect } from "react"; export default function App() { const [name, setName] = useState(""); const prevName = useRef(name); useLayoutEffect(() => { prevName.current = name; }, [name]); return ( <div className="App"> <input value={name} onChange={(e) => { setName(e.target.value); }} ></input> <div>Your name is {name}</div> <div>Your previous name is {prevName.current}</div> </div> ); }Hook useEffect se ejecuta de forma asíncrona y, por lo general, después de que el DOM se renderice o monte, mientras que useLayoutEffect se ejecuta de forma síncrona y antes de que el DOM se renderice o monte.
Ambos ocurren después de que los cambios se hayan realizado en el DOM. Lo especial de los efectos de diseño es que si establece el estado durante el efecto de diseño, el renderizado resultante se realizará de forma sincrónica. Para los efectos normales, si establece el estado, se volverá a procesar pronto, pero no de forma sincrónica. Si nunca establece el estado (como en su ejemplo), no hará mucha diferencia cuál use.
La aplicación más común de useLayoutEffect es que desea renderizar una vez, medir las cosas en el dom y luego volver a renderizar sin que el usuario vea las cosas temporales que tenía en el dom.