roderickhsiao / react-in-viewport

Detect if React component is in viewport
https://roderickhsiao.github.io/react-in-viewport
MIT License
350 stars 30 forks source link

On firstTime Rendering it dosent work #134

Open shishirkj opened 4 months ago

shishirkj commented 4 months ago
import ContainerHeader from '@/presentation/components/channels/common/ContainerHeader';
import { PostItem } from '@/presentation/components/post/postItem';
import type React from 'react';
import { RefObject, useEffect, useMemo, useRef, useState } from 'react';
import { FlatList, View } from 'react-native';
import usePost from '@/application/hooks/post/usePost';
import { authState } from '@/application/slice/authSlice';
import { postState, setLimit, setPage } from '@/application/slice/postSlice';
import { channelId } from '@/constants/channelIdOptions';
import { PostError } from '@/error/postException';
import { useQuery } from '@tanstack/react-query';
import { useDispatch, useSelector } from 'react-redux';
import { createShimmerPlaceHolder } from 'expo-shimmer-placeholder';
import { LinearGradient } from 'expo-linear-gradient';
import NoMessage from '../common/NoMessage';
import throttle from 'lodash.throttle';
import handleViewport, { type InjectedViewportProps } from 'react-in-viewport';

const Block = (props: InjectedViewportProps<HTMLDivElement>) => {
    const { inViewport, forwardedRef } = props;
    const color = inViewport ? '#217ac0' : '#ff9800';
    const text = inViewport ? 'In viewport' : 'Not in viewport';
    return (
      <div className="viewport-block" ref={forwardedRef}>
        <h3>{ text }</h3>
        <div style={{ height: '1px', background: color }} />
      </div>
    );
  };

  const ViewportBlock = handleViewport(Block, /** options: {}, config: {} **/);

const IntroductionScreen = () => {
    const ShimmerPlaceHolder = createShimmerPlaceHolder(LinearGradient);
    const { posts, loading } = useSelector(postState);
    const { user } = useSelector(authState);
    const { handleFetchAllPosts } = usePost();
    const dispatch = useDispatch();
    const { limit, page } = useSelector(postState);

    const fetchIntroductionPost = async () => {
        try {
            return await handleFetchAllPosts(channelId.introduction);
        } catch (error) {
            if (error instanceof PostError) {
                console.log('🚀 ~ fetchRules ~ error:', error);
            }
        }
    };

    useQuery(['fetch-introductionPosts'], fetchIntroductionPost, {
        enabled: !!user,
    });
    const loadMorePosts = async () => {
        console.log('loadMorePosts');
        const newLimit = limit + 5;
        dispatch(setLimit(newLimit));
        await fetchIntroductionPost();
    };

    return (
        <View style={{ marginBottom: 64, paddingBottom: 12 }} className="bg-white w-[816px] px-8 border-b border-gray-200  min-h-full">
            <ContainerHeader />
            <View className="mb-4 border-b border-gray-200" />
            {loading ? (
                <>
                    <ShimmerPlaceHolder
                        style={{
                            backgroundColor: 'transparent',
                            flex: 1,
                            borderRadius: 25,
                            width: 750,
                            maxHeight: 128,
                            margin: 8,
                            overflow: 'hidden',
                        }}
                    />
                    <ShimmerPlaceHolder
                        style={{
                            backgroundColor: 'transparent',
                            flex: 1,
                            borderRadius: 25,
                            width: 750,
                            maxHeight: 128,
                            margin: 8,
                            overflow: 'hidden',
                        }}
                    />
                </>
            ) : posts.length === 0 ? (
                <View className="flex items-center justify-center h-screen ">
                    <NoMessage />
                </View>
            ) : (
                <View className="flex-1 space-y-4">
                    {
                        !loading &&
                            posts
                                .slice()
                                .reverse()
                                .map((introductionPost) => <PostItem key={introductionPost.posts.postId} showLike={false} showBookMark={false} showComment={false} post={introductionPost.posts} name={introductionPost.name} />)
                        // <FlatList
                        //  data={posts}
                        //  renderItem={({ item }) => <PostItem key={item.posts.postId} showLike={false} showBookMark={false} showComment={false} post={item.posts} name={item.name} />}
                        //  keyExtractor={(item) => item.posts.postId.toString()}
                        //  onEndReached={loadMorePosts}
                        //  onEndReachedThreshold={0.5}

                        // />
                    }
                        <ViewportBlock onEnterViewport={() => console.log('enter')} onLeaveViewport={() => console.log('leave')} />
                </View>
            )}
        </View>
    );
};

export default IntroductionScreen;
fridaystreet commented 2 months ago

was just about to come and try and find this issue or raise it. It doesn't set InViewPort to true on load if it's already in the viewport. I'm assuming becuase it's now using the intersectionObserver? it's only firing on an actual intersection, and I assume doesn't have any onload detection? Massive assumptions at this stage as haven't looked at code, but any thoughts on fixing this?

Cheers

fridaystreet commented 2 months ago

I'm not normally one for jumping ship and this has been a great library, but we really need this to work. Seem react-intersection-observer works on initial load aswell

https://github.com/thebuilder/react-intersection-observer

roderickhsiao commented 2 months ago

oh sorry I missed the message, let me check

roderickhsiao commented 2 months ago

Could you try using the hook directly instead of using the depreacted HOC?

Yes we are using intersection observer

roderickhsiao commented 1 month ago

could you try to update the library and try again?