#javascript #reactjs #pagination #lazy-loading #react-context
Вопрос:
Итак, у меня есть 2 компонента. Компонент блог/последние сообщения, который будет отображать последние сообщения, когда пользователь прокручивает страницу вниз, он загружает следующую страницу.
другим компонентом является поставщик контекста, который охватывает все приложение.
Последние.jsx
/*REACT*/
import React, { useContext, useEffect } from 'react';
import { Link } from 'react-router-dom';
/*MUI COMPONENTS*/
import { Container } from '@material-ui/core';
/*MUI ICONS*/
import BannerSmall from '/storage/assets/images/banner-small.jpg';
import BannerBig from '/storage/assets/images/banner.jpg';
/*CONTEXT*/
import { Post } from '../../components/providers/PostProvider';
const Recents = () => {
const { posts, nextPage, getPosts } = useContext(Post);
const handleScroll = async (e) => {
const { scrollTop, clientHeight, scrollHeight } = e.currentTarget;
if (scrollTop clientHeight >= scrollHeight) {
getPosts();
}
};
const root = document.getElementById('root');
const registerScrollEventListener = () => root.addEventListener('scroll', handleScroll);
const unregisterScrollEventListener = () => root.removeEventListener('scroll', handleScroll);
useEffect(() => {
registerScrollEventListener();
return () => {
unregisterScrollEventListener();
};
}, []);
return (
<Container disableGutters className="blog-recents">
<div className="image-container">
<img className="image" src={BannerSmall} srcSet={`${BannerSmall} 800w, ${BannerBig} 1280w`}
alt="Banner"/>
</div>
{posts.length > 0 amp;amp; posts.map(post => (
<div className="post" key={post.id}>
<Link className="link" to={'/blog/posts/' post.slug}>
<div className="image-container">
<img className="image" src={post.imagePath}/>
</div>
</Link>
<div className="content">
<h1 className="title">{post.title}</h1>
<p className="description">Lorem ipsum dolor sit amet, consectetur adipisicing
elit. Animi culpa dolores ducimus et explicabo ipsa neque, nostrum saepe sequi
similique. At blanditiis commodi laborum optio pariatur placeat saepe, voluptatem.
Dolorem!</p>
</div>
</div>
))}
</Container>
);
};
export default Recents;
PostProvider.jsx
/*REACT*/
import React, { createContext, useEffect, useState } from 'react';
import axios from 'axios';
export const Post = createContext({});
export default (props) => {
const [posts, setPosts] = useState([]);
const [nextPage, setNextPage] = useState('/api/posts');
const [loading, setLoading] = useState(false);
const getPosts = () => {
if (loading) return;
setLoading(true);
axios.get(nextPage).then(r => {
console.log(nextPage);
setPosts([...posts, ...r.data.data]);
setNextPage(r.data.links.next);
setLoading(false);
}).catch((r) => {
setLoading(false);
});
};
useEffect(() => {
getPosts();
}, []);
return <Post.Provider value={{ posts, nextPage, getPosts }} children={props.children}/>;
};
I have no clue as to what to do. The only way I have made it work is using a class context. But I really wanted to try functional components. I even used a combined state of
const [state, setState] = useState(
{
posts: [],
loading: false,
nextPage: 'api/posts/'
});
есть какие-либо предложения относительно того, почему штат обновляется ОЧЕНЬ нерегулярно?
иногда он запускает getPosts()
функцию только тогда, когда в функции getPosts присутствует console.log.
Я просто хочу, чтобы он вызывался всякий раз, когда пользователь прокручивает страницу вниз, а затем переходит на следующую страницу.