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

如何在React Native搭配Redux Saga实现FlatList加载更多功能

React Native + Redux Saga 实现FlatList上拉加载更多修复方案

核心问题梳理

现有代码存在几个明显问题:

  • 变量拼写不一致:useSelector返回的变量命名为listing,但FlatList中使用的是listings,会导致数据读取失败
  • loadMore方法仅修改了本地页码状态,没有触发Saga监听的GET_ADS action发起新页请求
  • 之前尝试的数据拼接写法错误:state.concat中state是存储对象,本身没有数组的concat方法,需要取state.data进行拼接
  • 缺少加载状态判断,可能会触发重复的上拉加载请求

分步代码调整

2.1 调整SearchScreen逻辑

首先修正变量拼写,补充加载状态判断和请求触发逻辑:

// 从Redux中同时取数据和加载状态
const { data: listings, loading } = useSelector((state) => state.adData);

// 首次进入页面触发第一页请求
useEffect(() => {
  dispatch({ type: Actions.GET_ADS, page: 1 });
}, [dispatch])

const loadMore = () => {
  // 加载中直接返回,避免重复请求
  if (loading) return;
  const nextPage = pageCurrent + 1;
  setpageCurrent(nextPage);
  // 触发分页请求action,传递新页码
  dispatch({ type: Actions.GET_ADS, page: nextPage });
};

// FlatList可选补充底部加载提示
<FlatList
  showsVerticalScrollIndicator={false}         
  data={listings}
  keyExtractor={keyExtractor}
  removeClippedSubviews={true}
  onEndReached={loadMore}
  onEndReachedThreshold={0.8}
  windowSize={15}
  getItemLayout={getItemLayout}
  renderItem={renderItem}
  // 底部加载中提示
  ListFooterComponent={() => loading ? <ActivityIndicator style={{ paddingVertical: 20 }} /> : null}
/>

2.2 调整Reducer数据拼接逻辑

首先确保初始状态的data为空数组,再修改成功回调的数据拼接逻辑:

// 初始状态示例
const initState = {
  data: [],
  loading: false
}

export default function productReducer(
  state = initState,
  { type, payload, error }
) {
  switch (type) {
    case Actions.GET_ADS:
      return { ...state, loading: true };
    case Actions.GET_ADS_SUCCESS:
      return {
        ...state,
        // 新旧分页数据拼接
        data: [...state.data, ...payload],
        loading: false
      };
    case Actions.GET_PRODUCT_ATTRIBUTE_ERROR:
      return { ...state, loading: false, error };
    default:
      return state;
  }
}

如果需要支持下拉刷新功能,可以在请求action中加isRefresh标识,当isRefresh为true时直接用data: payload覆盖旧数据即可。

2.3 补充Saga监听配置

确保Saga正确监听GET_ADS action:

import { takeEvery } from 'redux-saga/effects';

function* fetchListingsSaga({ page }) {
  try {
    const data = yield call(getListings, { page });
    yield put({ type: Actions.GET_ADS_SUCCESS, payload: data.data.response });
  } catch (e) {
    yield put({ type: Actions.GET_PRODUCT_ATTRIBUTE_ERROR, error: e });
  }
}

// 根Saga中添加监听
function* rootSaga() {
  yield takeEvery(Actions.GET_ADS, fetchListingsSaga);
}

注意事项

  • 确保分页接口返回的是当前页的数组格式数据,不要返回全量数据
  • keyExtractor必须使用列表项的唯一id作为key,不要使用数组下标,避免加载更多后列表渲染错乱
  • 若需要处理无更多数据的场景,可在Redux中新增hasMore字段,接口返回总条数/是否有下一页标识后更新该字段,loadMore中判断hasMore为false时直接返回即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 12:45:02