9.5.6 페이지네이션 구현하기

    프로필 화면에서도 페이지네이션을 구현해봅시다. 포스트 목록 화면에서 구현한 방법과 동일합니다. 포스트를 조회하는 과정에서 userId 옵션이 추가될 뿐이죠.

    components/Profile.js

    (...)
    import {
      (...)
      RefreshControl,
    } from 'react-native';
    import {getNewerPosts, getOlderPosts, getPosts, PAGE_SIZE} from '../lib/posts';
    
    function Profile({userId}) {
      const [user, setUser] = useState(null);
      const [posts, setPosts] = useState(null);
    
      const [noMorePost, setNoMorePost] = useState(false);
      const [refreshing, setRefreshing] = useState(false);
    
      const onLoadMore = async () => {
        if (noMorePost || !posts || posts.length < PAGE_SIZE) {
          return;
        }
        const lastPost = posts[posts.length - 1];
        const olderPosts = await getOlderPosts(lastPost.id, userId);
        if (olderPosts.length < PAGE_SIZE) {
          setNoMorePost(true);
        }
        setPosts(posts.concat(olderPosts));
      };
    
      const onRefresh = async () => {
        if (!posts || posts.length === 0 || refreshing) {
          return;
        }
        const firstPost = posts[0];
        setRefreshing(true);
        const newerPosts = await getNewerPosts(firstPost.id, userId);
        setRefreshing(false);
        if (newerPosts.length === 0) {
          return;
        }
        setPosts(newerPosts.concat(posts));
      };
    
      useEffect(() => {
        getUser(userId).then(setUser);
        getPosts({userId}).then(setPosts);
      }, [userId]);
    
      if (!user || !posts) {
        return (
          <ActivityIndicator style={styles.spinner} size={32} color="#6200ee" />
        );
      }
    
      return (
        <FlatList
          style={styles.block}
          data={posts}
          renderItem={renderItem}
          numColumns={3}
          keyExtractor={(item) => item.id}
          ListHeaderComponent={
            <View style={styles.userInfo}>
              <Avatar source={user.photoURL && {uri: user.photoURL}} size={128} />
              <Text style={styles.username}>{user.displayName}</Text>
            </View>
          }
          onEndReached={onLoadMore}
          onEndReachedThreshold={0.25}
          ListFooterComponent={
            !noMorePost && (
              <ActivityIndicator
                style={styles.bottomSpinner}
                size={32}
                color="#6200ee"
              />
            )
          }
          refreshControl={
            <RefreshControl onRefresh={onRefresh} refreshing={refreshing} />
          }
        />
      );
    }
    
    const renderItem = ({item}) => <PostGridItem post={item} />;
    
    const styles = StyleSheet.create({
      (...)
      bottomSpinner: {
        height: 128,
      }
    });
    
    export default Profile;

    FeedScreen의 코드를 복사/붙여넣기한 수준으로 매우 비슷합니다. 차이점은 getNewerPostsgetOlderPostsuserId 파라미터를 넣고, onEndreachedthreshold0.25로 설정했다는 점입니다. 이 값을 낮춤으로써 화면의 끝에 더 가까워져야 다음 포스트를 불러오게 됩니다.

    이제 화면에서 스크롤해보세요. 페이지네이션이 잘 이뤄지나요? 새 사진을 업로드하고 화면을 아래로 끌어당겨보세요. 새로운 사진이 잘 추가되나요?

    신간 소식 구독하기
    뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.