You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

react-infinite-scroll-component仅触发一次 无法加载更多VideoThumbnail组件

问题解决方案

核心原因

你遇到的内容替换而非追加的问题,本质是Redux Reducer处理HOME_VIDEOS_SUCCESS时直接覆盖了原视频数组,没有做新旧数据拼接,其次存在无限滚动组件配置不完善的问题。

具体修复步骤

1. 修正Redux Reducer逻辑

找到你对应homeVideos的reducer文件,修改HOME_VIDEOS_SUCCESS的处理逻辑,将新返回的视频列表拼接到原有列表末尾,示例代码如下:

const initialState = {
  videos: [],
  nextPageToken: null,
  loading: false,
  error: null
}

export const homeVideosReducer = (state = initialState, action) => {
  switch (action.type) {
    case HOME_VIDEOS_REQUEST:
      return {
        ...state,
        loading: true
      }
    case HOME_VIDEOS_SUCCESS:
      return {
        ...state,
        loading: false,
        // 核心修改:拼接新旧视频数组,而不是直接覆盖
        videos: [...state.videos, ...action.payload.videos],
        nextPageToken: action.payload.nextPageToken
      }
    case HOME_VIDEOS_FAIL:
      return {
        ...state,
        loading: false,
        error: action.payload
      }
    default:
      return state
  }
}

2. 完善无限滚动组件配置

你当前的InfiniteScroll组件hasMore写死为true,会导致没有更多数据时仍重复发送请求,需要从Redux中读取nextPageToken做判断,同时可以添加加载提示提升体验,修改组件代码如下:

const TrendingPage = () => {
  const dispatch = useDispatch();
  // 同时取出nextPageToken和loading状态
  const { videos, nextPageToken, loading } = useSelector((state) => state.homeVideos);

  const fetchData = () => {
    // 非加载状态下才发请求,避免重复触发
    if (!loading) {
      dispatch(getPopularVideos());
    }
  };

  useEffect(() => {
    dispatch(getPopularVideos());
  }, [dispatch]);

  return (
    <div className="page-container wrap-content">
      <InfiniteScroll
        dataLength={videos.length}
        next={fetchData}
        // 存在下一页token时才允许加载更多
        hasMore={!!nextPageToken}
        // 加载时显示的提示内容
        loader={<h4>加载中...</h4>}
      >
        {videos.map((item) => (
          <VideoThumbnail
            key={item.id}
            image={item.snippet.thumbnails.medium.url}
            time={moment
              .utc(
                moment.duration(item.contentDetails.duration).asSeconds() * 1000
              )
              .format("mm:ss")}
            owner={item.snippet.channelTitle}
            name={item.snippet.title}
            minWidth="230px"
          />
        ))}
      </InfiniteScroll>
    </div>
  );
};

可选优化

你的getPopularVideosaction逻辑本身没有问题,可添加没有nextPageToken时不发送请求的判断,减少无效请求:

export const getPopularVideos = () => async (dispatch, getState) => {
  try {
    // 没有下一页token且已有视频数据时直接终止,避免无效请求
    if (!getState().homeVideos.nextPageToken && getState().homeVideos.videos.length > 0) return;
    
    dispatch({
      type: HOME_VIDEOS_REQUEST,
    });

    const { data } = await request.get("/videos", {
      params: {
        part: "snippet, contentDetails, statistics",
        chart: "mostPopular",
        regionCode: "TR",
        maxResults: 20,
        pageToken: getState().homeVideos.nextPageToken,
      },
    });

    dispatch({
      type: HOME_VIDEOS_SUCCESS,
      payload: {
        videos: data.items,
        nextPageToken: data.nextPageToken,
      },
    });
  } catch (error) {
    console.log(error);
    dispatch({
      type: HOME_VIDEOS_FAIL,
      payload: error.message,
    });
  }
};

内容的提问来源于stack exchange,提问作者Ziya Arslan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 11:15:04