Tengo una función newsFeed la que llama useEffect y realiza una solicitud a un punto final para obtener todas las publicaciones realizadas por el usuario que inició sesión, así como por los usuarios a los que sigue, y luego guarda la respuesta de datos al estado:
const [posts, setPosts] = useState([]) const [page, setPage] = useState(1) useEffect(() => { newsFeed(); }, [] const newsFeed = async () => { await axios.post( `${process.env.REACT_APP_API}/news-feed/${page}`, ) .then((res) => { setPosts(res.data); setPage(page + 1); }) .catch((err) => { console.log(err); }); }; router.post('/news-feed/:page', newsFeed); exports.newsFeed = async (req, res) => { try { const user = await User.findById(req.body.user._id); let following = user.following; following.push(req.body.user._id); const currentPage = req.params.page || 1; const perPage = 5; const posts = await Post.find({ postedBy: { $in: following } }) .skip((currentPage - 1) * perPage) .sort({createdAt: -1}) .limit(perPage); res.json(posts); } catch (err) { console.log(err); } }; Quiero usar react-infinite-scroll-component para obtener solo las primeras 20 publicaciones en la carga de la página, luego otras 20 cuando el usuario se desplaza hacia abajo, etc.
Actualmente tengo este código para renderizar las publicaciones:
<div id='scrollableDiv' style={{ overflow: 'auto' }}> <InfiniteScroll dataLength={20} next={newsFeed} hasMore={true} loader={<FontAwesomeIcon icon={faSpinner} spin />} endMessage={ <p style={{ textAlign: 'center' }}> <b>Yay! You have seen it all</b> </p> } scrollableTarget='scrollableDiv' > {posts.map((post) => ( ...)} </InfiniteScroll> </div>Lo que sucede ahora es que solo se procesan las primeras 20 publicaciones, y el control giratorio de carga se muestra continuamente a continuación.
Intenté agregar la page como una dependencia a la devolución de llamada useEffect y esto da como resultado que se carguen las publicaciones en bloques de 20, sin embargo, se procesan automáticamente cada segundo y se superponen al bloque anterior como si la aplicación estuviera literalmente cambiando la página y cuando todos tienen se muestra una pantalla vacía.
Su problema parece ser que su backend devuelve todos los registros cada vez que lo llama, ya que no se le pasan parámetros:
await axios.post( `${process.env.REACT_APP_API}/news-feed`, )Esto no es consistente con la documentación del componente que establece:
Los datos se pasan como elementos secundarios al componente InfiniteScroll y los datos también deben contener elementos anteriores. por ejemplo, datos iniciales = [1, 2, 3] y luego la siguiente carga de datos debe ser [1, 2, 3, 4, 5, 6].
Por lo tanto, debe decirle a su backend qué conjunto de elementos devolver y luego agregar esos elementos a las publicaciones que ya cargó en llamadas anteriores.
Por ejemplo, mantenga una referencia de la página que necesita devolver y llame al backend con un parámetro:
//In state declaration const [pageNumber, setPageNumber] = useState(1); //In loader function await axios.post( `${process.env.REACT_APP_API}/news-feed/{pageNumber}`, ) Donde pageNumber es una variable que mantienes en estado con el número de página actual, luego la incrementas cada vez que recibes elementos. Algo del estilo de:
await axios.post( `${process.env.REACT_APP_API}/news-feed/{pageNumber}`, ) .then((res) => { let newPosts = posts; newPosts.concat(res.data); setPosts(newPosts); setPageNumber(pageNumber + 1); })Si no puede modificar el backend para admitir la paginación, tendrá que recuperar todos los registros cada vez y dividirlos para seleccionar los que necesita agregar. No es terriblemente difícil pero sí muy ineficiente. Algo como esto:
//In state declaration const [pageNumber, setPageNumber] = useState(0); //0 based //In data loader await axios.post( `${process.env.REACT_APP_API}/news-feed`, ) .then((res) => { let newPosts = posts; let start = (pageNumber === 0) ? 0 : (pageNumber * 20) - 1; let addPosts = res.data.slice(start, 20); newPosts = newPosts.concat(addPosts); setPosts(newPosts); setPageNumber(pageNumber + 1); })Escribí esto con prisa, así que asegúrese de verificar la coherencia y el final de los registros. Entiendes la idea. :-)