@aleshaykovlev
html, css, js, node, webpack, sass, react

Почему пагинация не работает?

Есть всего 3 поста. На странице по умолчанию 2. При прокрутке до конца должен добавиться еще один, но приходит пустой массив, что может быть не так?

На главной странице:
const [currentPage, setCurrentPage] = React.useState<number>(1);
	const [fetching, setFetching] = React.useState<boolean>(true);

	React.useEffect(() => {
		if (fetching) {
			dispatch(getPostsAsyncAction(
				setText,
				{ limit: 2, page: currentPage },
				setCurrentPage,
				setFetching,
				posts
			));
		}
	}, [fetching]);

	React.useEffect(() => {
		document.addEventListener("scroll", scrollPosts);

		return function () {
			document.removeEventListener("scroll", scrollPosts);
		};
	}, []);

	function scrollPosts(event: any) {
		const { scrollHeight, scrollTop } = event.target.documentElement;
		const height = window.innerHeight;

		// долистали до конца страницы
		if (scrollHeight - (scrollTop + height) < 100) {
			setFetching(true);
		}
	}


getPostsAsyncAction:
function getPostsAsyncAction(
	setText: React.Dispatch<React.SetStateAction<string>>,
	pagination: IPagination,
	setPage: React.Dispatch<React.SetStateAction<number>>,
	setFetching: React.Dispatch<React.SetStateAction<boolean>>,
	posts: Array<IPost>
) {
	return (dispatch: React.Dispatch<any>) => {
		getAllPosts(pagination)
			.then((data) => {
				const { success, message } = data;

				if (!success) {
					setText(message);
					return;
				}

				dispatch(setPosts([...posts, ...data.posts]));
				setPage((prevState) => prevState + 1);
			})
			.finally(() => setFetching(false));
	};
}


Сервер:
const { _limit, _page } = req.query;
		const queryForFindPosts = `SELECT * FROM post ORDER BY date DESC LIMIT $1 OFFSET $2`;

		console.log(_limit, _page);

		new Promise((resolve) => resolve(db.query(queryForFindPosts, [_limit, _page])))
			.then((posts) => {
				let newPosts = [];

				for (let i = 0; i < posts.rows.length; i++) {
					// ...code
           }

				console.log("=======================================");
				console.log(newPosts.map(p => p.id));
				return res.status(200).json({ success: true, posts: newPosts });
			})


В итоге на сервере при первой прокрутке выводится:
2 1
=======================================
[ 84, 83 ]
2 1
=======================================
[ 84, 83 ]
2 3
=======================================
[]
2 4
=======================================
[]
  • Вопрос задан
  • 108 просмотров
Пригласить эксперта
Ответы на вопрос 1
Krasnodar_etc
@Krasnodar_etc
fundraiseup
По логам видно, что у вас вместо 2 2 приходит 2 3 (page 3)

Вообще, слушать событие скролла больно, потому что слушатель отрабатывает чуть ли не на каждый проскроленный пиксель. Я думаю, происходит следующее:

Первый раз scrollPosts вызывается 2 раза почти одновременно, поэтому в серверном логе вы 2 раза видите параметры 2 1
Когда оба запроса вернутся с ответом, пейдж в стейте 2 раза увеличится на 1
Следующий запрос отправится уже с пейдж = 3, а столько данных у вас нет

Рекомендую погуглить "infinity scroll intersection observer", сейчас подгрузку чаще всего делают так

Или после первого срабатывания эффекта обнулять флаг fetching:
React.useEffect(() => {
    if (fetching) {
      ...
    }
  setFetching(false);
  }, [fetching]);
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы