0

I want to make infinite loading using useSWRInfinite.

import React, { useRef, useState } from 'react';
import { useHistory } from 'react-router-dom';
import * as S from './styles';
import CardList from '../CardList/CardList';
import Card from '../Card/Card';
import * as C from '../../utils/constants';
import { movieInfo, popularResponseType } from '../../types';
import { useRequest } from '../../hooks/useRequest';

const Popular: React.FC = () => {
    const history = useHistory();
    const loadingRef = useRef<HTMLDivElement>(null);
    const { movies, error, isLoadingMore, size, setSize, isReachingEnd, mutate } = useRequest();
    if (error) {
        return <h1>Somthing went wrong</h1>;
    }
    if (!movies) {
        return <h1>Loading...</h1>;
    }
    const onClick = (movie: movieInfo, id: number) => {
        history.push(`/detail/${id}`, { movie });
    };
    return (
        <S.Container>
            <CardList>
                {movies.map((info: movieInfo, id: number) => (
                    <Card
                        title={info.title}
                        onClick={onClick}
                        id={info.id}
                        key={id}
                        image={`${C.IMAGE_URL_ORIGINAL}${info.backdrop_path}`}
                        movie={info}
                    ></Card>
                ))}
                <div ref={loadingRef}>{movies ? '' : 'loading'}</div>
            </CardList>
            <button onClick={() => setSize(size + 1)}>load more</button>
        </S.Container>
    );
};

export default Popular;

This is code that get movie api from tmdb using useSWRInfinite. after click load more button, useSWRInfinite get data successful.

When first render, card component works well. but after click load more, the component Card is not working and for each item. All data works well with show image and show title, but the image size is not fit and the animation of card is not working.

this is the hooks using useSWRInfinite

import React from 'react';
import { useSWRInfinite } from 'swr';
import { movieInfo, popularResponseType } from '../types';
import { fetcher } from '../utils/request';
import * as C from '../utils/constants';

export const useRequest = () => {
    const { data, error, size, setSize, mutate } = useSWRInfinite(
        (index) =>
            `${C.API_URL}/movie/popular?api_key=${
                process.env.REACT_APP_API_KEY
            }&language=ko-KR&page=${index + 1}`,
        fetcher
    );
    const PAGE_SIZE = 20;

    const response: Array<popularResponseType> = data ? [].concat(...data) : [];
    const movies: Array<movieInfo> = response.reduce(
        (acc: Array<movieInfo>, cur: popularResponseType) => acc.concat(...cur.results),
        []
    );
    const isLoadingInitialData = !data && !error;
    const isLoadingMore =
        isLoadingInitialData || (size > 0 && data && typeof data[size - 1] === 'undefined');
    const isEmpty = data?.[0]?.length === 0;
    const isReachingEnd = isEmpty || (data && data[data.length - 1]?.length < PAGE_SIZE);

    return { movies, error, isLoadingMore, size, setSize, isReachingEnd, mutate };
};

useRequest.ts

4

0 回答 0