Que horrible es eso:
useLayoutEffect(() => {
setWidth(ganttContainerRef.current.offsetWidth);
setHeight(ganttContainerRef.current.offsetHeight);
}, [])
useLayoutEffect(() => {
if (width > 0) {
setGanttReady(true);
}
}, [width])
useLayoutEffect(() => {
if (ganttReady) {
ganttRef.current.scrollTo({ left: 80 * 80 / 7 + 40 });
}
}, [ganttReady]);
es decir, renderizar un componente en 3 pasos separados...
Si renderizo 1 y 2 al mismo tiempo, el ancho del contenedor será 0 (primer renderizado) porque 2 aún no se muestra.
No importa lo que haga, si hago const top = refs.current[initiative.id].offsetTop; , offsetTop tendrá un valor como si el ancho aún fuera 0. offsetTop no se actualiza con una nueva representación.
Con el código publicado arriba, funciona bien, pero ¿qué tan malo es? ¿Es factible renderizar un componente en varias fases o realmente estoy pirateando el comportamiento normal de React?
Con el código publicado arriba, funciona bien, pero ¿qué tan horrible es? ¿Es factible representar un componente en varias fases o realmente estoy pirateando el comportamiento normal de React?
No diría que es horrible, se podría decir que no es muy eficiente, pero no me preocuparía si no se nota.
Puedes refactorizarlo a algo como esto:
useLayoutEffect(() => {
let offsetWidth = ganttContainerRef.current.offsetWidth;
setWidth(offsetWidth);
setHeight(ganttContainerRef.current.offsetHeight);
if (offsetWidth > 0) {
setGanttReady(true);
ganttRef.current.scrollTo({ left: (80 * 80) / 7 + 40 });
}
}, []);
Pero el problema con este enfoque es que, como puede ver, solo se ejecuta en el montaje; que está bien si eso es lo que quieres. Entonces, con su enfoque anterior aquí:
useLayoutEffect(() => {
if (width > 0) {
setGanttReady(true);
}
}, [width])
tenías la ventaja de que si el width cambiaba, entonces podías actuar en consecuencia, no lo obtienes con mi versión.
Así que depende.