Swiper.js событие onReachEnd срабатывает дважды

Использую свайпер для показа карточек постов и по идее, если потянуть слайды, находясь в конце списка, должна срабатывать функция, которая показывает спиннер и подтягивает новые поста. Все работает, но функция срабатывает дважды, если использовать юзСтейт.

На английском стеке мне помогли решить с помощью юзРеф, но мне это кажется костылем. Вопроса два:

  1. Почему без юзРеф функция срабатывает дважды? Я пробовал делать рядом кнопку и вешать на нее то же событие, все отрабатывает один раз. Есть подозрение, что это нюанс самого свайпера. Когда я тяну за пределы списка, событие отрабатывает дважды - когда тяну и отпускаю, но это лишь догадка.

  2. Можно ли решить, не прибегая к юзРеф?

    const PostList: FC = () => {
         const [postsData, setPostsData] = useState<TPost[] | undefined>();
         const [page, setPage] = useState(0);
         const [loadingMorePosts, setLoadingMorePosts] = useState(false);
         const [loading, setLoading] = useState(true);
         const [error, setError] = useState(false);
         const isShowMoreRunning = useRef(false);
    
         const showMore = () => { 
             setLoadingMorePosts(true);
             setPage(prevPage => prevPage + 1);
             console.log("SHOWMORE");
         }
    
         // const showMore = () => {
         //     if (!isShowMoreRunning.current) {
         //         isShowMoreRunning.current = true;
         //         setLoadingMorePosts(true);
         //         setPage(prevPage => prevPage + 1);
         //     }
         // };
    
         useEffect(() => {
             getPosts(page)
                 .then(newPosts => newPosts.json() as Promise<TPostData>)
                 .then(newPosts => {
                     setPostsData(prevState => [...(prevState ?? []), ...newPosts.posts]);
                     setLoadingMorePosts(false);
                     setLoading(false);
                 })
                 .catch(e => {
                     setError(true);
                     console.log(e.message);
                     setLoading(false);
                     setLoadingMorePosts(false);
                 })
         }, [page]);
    
         // useEffect(() => {
         //     isShowMoreRunning.current = false;
         // }, [postsData]);
    
         if (loading) return <Spinner />;
    
         return (
             <div className="post-list">
                 <div className="post-list__menu">
                     <div className="post-list__menu-left">
                         <span>user stories</span>
                         <span className='disabled'>last change<span className='sticker'>soon</span></span>
                     </div>
                     <AddStoryModal />
                 </div>
                 <div className='post-list__postitem-view'>
                     <Swiper
                         spaceBetween={10}
                         slidesPerView={"auto"}
                         touchMoveStopPropagation={true}
                         onReachEnd={showMore}
                         freeMode={{
                             enabled: true,
                             sticky: false,
                             momentumRatio: 0.4
                         }}
                         mousewheel={{
                             forceToAxis: false,
                             sensitivity: 1,
                             releaseOnEdges: true,
                           }}
                           modules={[Mousewheel, FreeMode]}
                         >
                         {error ? <ErrorSign /> : postsData?.map((post: TPost) => {
                             return <SwiperSlide key={post.id}>
                                 <PostItem key={post.id} title={post.title} body={post.body} userId={post.userId} id={post.id} />
                             </SwiperSlide>
                         })}
                         {loadingMorePosts && <SwiperSlide className='post-item-spinner' key={"spinner"}><Spinner loadingMorePosts={loadingMorePosts} /></SwiperSlide>}
                     </Swiper>
                 </div>
             </div>
         );
     };
    
     export default PostList;
    

Ответы (0 шт):