Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

154
Vistas
¿Por qué la función anidada del componente funcional usa un valor de estado obsoleto?

Mi componente obtiene y muestra publicaciones usando un desplazamiento infinito (a través de un IntersectionObserver ). La llamada a la API que realiza el componente depende del número actual de publicaciones recuperadas. Esto se pasa como compensación a la llamada a la API.

El efecto deseado es que, si la matriz de posts está vacía, su longitud es 0 y mi API devolverá las primeras 5 publicaciones. Cuando la última publicación en la interfaz de usuario se cruza con la ventana gráfica, se realiza otra búsqueda, pero esta vez la llamada a la API pasa un desplazamiento de 5, por lo que la API omite las primeras 5 publicaciones de la colección y devuelve las siguientes 5 en su lugar.

Aquí está mi código:

 export default function Feed() { const [posts, setPosts] = useState([]); const fetchPosts = async () => { const newPosts = await postAPI.getFeed(posts.length); setPosts((prevPosts) => [...prevPosts, ...newPosts]); }; useEffect(fetchPosts, []); const observerRef = useRef( new IntersectionObserver(([entry]) => { if (entry.isIntersecting) { observerRef.current.unobserve(entry.target); fetchPosts(); } }) ); const observePost = useCallback((node) => node && observerRef.current.observe(node), []); return ( <> {posts.map((post) => { const key = post._id; const isLastPost = key === posts.at(-1)._id; const callbackRef = !isLastPost ? undefined : observePost; //only if last post in state, watch it! return <PostCard {...{ key, post, callbackRef }} />; })} </> ); }

Sin embargo, cada vez que se llama a la función fetchPosts , el valor que usa para posts.length es 0, el número con el que se creó originalmente la función.

¿Alguien puede explicarme por qué el cierre de posts.length está obsoleto aquí? Pensé que cada vez que se vuelve a renderizar un componente, todas las funciones anidadas dentro de él se recrean desde cero. Como tal, seguramente la función fetchPosts debería usar el último valor de posts.length cada vez que se llama. ¡Cualquier ayuda es apreciada! :)

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Está creando un new IntersectionObserver en cada renderizado, no es una buena idea. Sin embargo, solo el primero de todos estos observadores creados, el que almacena en la referencia (la referencia que nunca se actualiza), es aquel en el que llama a observe() , y ese primer observador usa un cierre obsoleto sobre el valor inicial de posts

En su lugar, sugeriría crear los observadores de intersección dentro de la función observePost :

 const [posts, setPosts] = useState([]); const fetchPosts = useCallback(async () => { const newPosts = await postAPI.getFeed(posts.length); setPosts((prevPosts) => [...prevPosts, ...newPosts]); }, [posts.length]); // ^^^^^^^^^^^^ useEffect(fetchPosts, []); const observePost = useCallback((node) => { if (!node) return; const observer = new IntersectionObserver(([entry]) => { if (entry.isIntersecting) { observer.unobserve(entry.target); fetchPosts(); } }); observer.observe(node); }, [fetchPosts]); // ^^^^^^^^^^

Importante aquí es la dependencia de la devolución de llamada de observePost en la devolución de llamada de fetchPosts que tiene una dependencia de la longitud de las posts , para evitar quedarse obsoleto. Probablemente también sea posible resolver esto con referencias, pero no creo que sean necesarias aquí.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda