He buscado algunas respuestas con respecto a mi problema, pero encontré una relevante. Desafortunadamente, está incluso en el componente de clase, por lo que quiero restaurar la posición de desplazamiento después de volver a navegar en el componente funcional. Aquí compartiré el enlace del código fuente en Stackblitz
Hay pocos problemas aquí.
Primero:
setPosts(res.data.slice(0, 20), handleScrollPosition()); Verá, setter en useState no tiene un segundo argumento como this.setState() tiene. Pero, ¿puede preguntar por qué se llama a su handleScrollPosition ? (Ya que puede ver que se llama en el depurador). La razón es que ha escrito esto como handleScrollPosition() por lo que se llama inmediatamente. Para demostrar mi punto, si lo cambia para corregir el formulario "pasar una devolución de llamada":
setPosts(res.data.slice(0, 20), handleScrollPosition);Como ya tiene en la versión basada en clases, verá que nunca se llama. Similarmente,
[].map(() => {}, 1,2,3,4, handleScrollPosition()) también llamará a handleScrollPosition() aunque obviamente [].map() no procesa el sexto argumento.
Entonces, ¿qué debes hacer? Primero, pasemos la restauración de desplazamiento a un useEffect separado:
useEffect(() => { const scrollPosition = sessionStorage.getItem("scrollPosition"); if (scrollPosition) { window.scrollTo(0, parseInt(scrollPosition)); sessionStorage.removeItem("scrollPosition"); } }, []); obviamente no funcionó bien, ya que se llamará inmediatamente, antes de que se obtengan los datos. Así que agreguemos dependencia en las posts :
useEffect(() => {... }, [posts]); Pero no funcionará correctamente, todavía. La razón es que se activa en el procesamiento inicial cuando las posts están vacías... así que agreguemos la verificación "solo después de que se carguen las publicaciones":
useEffect(() => { if (posts.length) { const scrollPosition = sessionStorage.getItem("scrollPosition"); if (scrollPosition) { window.scrollTo(0, parseInt(scrollPosition)); sessionStorage.removeItem("scrollPosition"); } } }, [posts]);Ahora funciona como se esperaba y restaura la posición de desplazamiento.
PD: por cierto, no creo que escribir la posición de sessionStorage sea el mejor enfoque. Trabajar con varias pestañas hará un desastre. Si habla sin código de muestra, vería una alternativa haciendo una ruta separada "también la lista pero con la ID del elemento al que debemos desplazarnos". Y luego el enlace "volver a la lista" apuntará a esa ruta, con el paso de la ID de la entidad para la que actualmente está viendo los detalles.