useObserver hook doesn't work after re-render components
I have simple React app, that using two types of pagination: general by pages pagination and like twitter infinity pagination. For infinity pagination I used "useObserver" hook, to find the div element in the end of the page and if I see that element I load the next part of data. For general pagination I used general useState and general gooks. It doesn't matter. I want to dynamically switch between those two type of pagination by button click. I have two buttons: one button for pagination and second one for infinity pagination. When I clicked for the first one I render pages, when I pressed for the second one I re-render end of the page and remove pages and and div for infinity loading. But after re-render infinity loading my "useObserver" hook doesn't work.
My "useObserver" hook:
import { useEffect, useRef } from "react";
export const useObserver = (ref, canLoad, isLoading, callBack) => {
const observer = useRef();
useEffect(() => {
if (isLoading) return;
if (ref.current === undefined || ref.current === null) return;
if (observer === null) return;
if (observer.current) observer.current.disconnect();
var callBackObserver = (entries) => {
if (entries[0].isIntersecting && canLoad) {
callBack();
}
};
observer.current = new IntersectionObserver(callBackObserver);
observer.current.observe(ref.current);
}, [isLoading]);
};
My pagination switcher component:
import React from 'react';
import PostList from './PostList';
import Loader from './UI/loader/Loader';
import Pagination from './UI/pagination/Pagination';
export default function PaginationType({ isPagination, isPostLoading, removePost,
sortedAndSearchedPosts, title, page,
changePage, totalPages, lastElement }) {
if (isPagination) {
return (
<div>
{isPostLoading
? <div style={{ display: 'flex', justifyContent: 'center', marginTop: 50 }}><Loader /></div>
: <PostList
remove={removePost}
posts={sortedAndSearchedPosts}
title={title}
/>
}
<Pagination page={page}
changePage={changePage}
totalPages={totalPages}
/>
</div>
);
}
else {
return (
<div>
{isPostLoading &&
<div style={{ display: 'flex', justifyContent: 'center', marginTop: 50 }}><Loader /></div>
}
<PostList
remove={removePost}
posts={sortedAndSearchedPosts}
title={title}
/>
<div ref={lastElement} style={{ height: 20, background: 'red' }} />
</div>
);
}
};
Code from component that calling pagination switcher:
function Posts() {
const [isClassicPage, setClassicPage] = useState(true);
const [page, setPage] = useState(1);
const [posts, setPosts] = useState([]);
const [totalPages, setTotalPages] = useState(0);
const [fetchPosts, isPostLoading, postError] = useFetching(async (limit, page) => {
const response = await PostService.getAll(limit, page);
if (isClassicPage) {
setPosts(response.data);
}
else {
setPosts([...posts, ...response.data]);
}
const totalCount = response.headers['x-total-count'];
setTotalPages(getPageCount(totalCount, limit));
});
const lastElement = useRef();
useObserver(lastElement, page < totalPages, isPostLoading, () => {
setPage(page + 1);
});
return (
<div className="App">
<PaginationSwitcher setClassicPage={setClassicPage} />
{postError &&
<h1>Load error, so sorry :C</h1>
}
<PaginationType
isPagination={isClassicPage}
isPostLoading={isPostLoading}
removePost={removePost}
sortedAndSearchedPosts={sortedAndSearchedPosts}
title={"List of Posts 1"}
page={page}
changePage={changePage}
totalPages={totalPages}
lastElement={lastElement}
/>
</div>
);
}
export default Posts;
I expecting that after switching between two buttons and re-rendering components all will be work fine!