首页 > 解决方案 > React Native 如何分别对每个特定选项卡应用分页和加载更多?

问题描述

所以我目前有一个带有水平滚动视图的屏幕,其中包含我的类别选项卡。按下选项卡时,会在下面呈现一个平面列表,其中包含该类别特定的所有帖子(这部分工作正常)。

当屏幕最初加载时,默认选择第一个选项卡,并且该选项卡的所有帖子都呈现在下面。

现在,我在后端应用了分页,当我在邮递员上测试它时它正在工作。

我的问题是:

例如。如果我选择选项卡 1,则第一页 (page=0) 帖子被渲染,然后当我向下滚动时,页数增加到 2,但没有帖子被渲染。此外,当我选择选项卡 2 时,页数不会重置回 0,它会从选项卡 1 中停止的位置继续。

在选项卡 1 中,如果我继续向下滚动到第 10 页,那么我选择选项卡 2。

我想要的是选项卡 2 中的页数从 0 开始。

发生了什么选项卡 2 中的页数从 10 开始。

这是我的代码:

const getCategoryPostsAPI = (id,page)=>client.get(`/categories/${id}?page=${page}`)

function tabScreen({ navigation,route }) {
const [posts, setPosts] = useState([]);
const [error, setError] = useState(false);
const [loading, setLoading] = useState(false);
const[page,setPage]=useState(0);

const loadPosts = async (id) => {
setLoading(true);
const response = await getCategoryPostsAPI(id,page) //API call
setLoading(false);

if(refreshing) setRefreshing(false);
if (!response.ok) return setError(true);
setError(false);

if(page===0){
  setPosts(response.data)
}else{    
setPosts([...posts,...response.data]);
}};

useEffect(() => {
loadPosts(1,page);
}, [page]);

const categories = [
{
label: "Sports",
id: 1,
},
{
label: "Fashion",
id: 2,
},
{
label: "News",
id: 3,
},
{
label: "Cooking",
id: 4,
},
{
label: "Education",
id: 5,
}]

const handleLoadMore = ()=>{
setPage(page+1);
}

const[label,setLabel]=useState('Sports')

const setLabelFilter=label=>{
setLabel(label)
}

const [currentCategoryId, setCurrentCategoryId] = useState()

const toggleBrands = (categoryId) => {
setCurrentCategoryId(categoryId)
setLabel(label)
};

return (

<ScrollView 
horizontal 
showsHorizontalScrollIndicator={false}
>
{categories.map(e=>(
        <TouchableOpacity 
            key={e.id}
            onPress={()=>{toggleBrands(e.id),
                          setLabelFilter(e.label),
                          loadPosts(id=e.id),                        
                          setPage(0) // here i am trying to set the page to 0 on tab click 
                                        but it is not working
                          }}
            selected={e.id === currentCategoryId}
            >
        <Text>{e.label}</Text>
        </TouchableOpacity>
))}
</ScrollView>

<FlatList
  data={currentCategoryId ? posts.filter(post=>post.categoryId===currentCategoryId
    ):posts.filter(post=>post.categoryId===1)} 
  keyExtractor={(post) => post.id.toString()}
  renderItem={({ item,index }) => (
   <Card
      title={item.title}
      subTitle={item.subTitle}
      onPress={() => navigation.navigate(routes.POST_DETAILS, {post:item,index})}
    />
      onEndReached={handleLoadMore}
      onEndReachedThreshold={0.000001}
      initialNumToRender={10}
  )}
/>

我认为我实现了我的分页错误,因此为什么我的 handleloadmore 不起作用,因为我在不同的屏幕中使用了相同的 handleloadmore 并且它正在工作。

标签: react-nativepagination

解决方案


我猜您希望在单击另一个类别时将页面重置为 0,并且您希望在滚动单个类别时对数据进行分页。如果是这样,试试这个

const getCategoryPostsAPI = (id, page) => client.get(`/categories/${id}?page=${page}`);

const categories = [
  {
    label: "Sports",
    id: 1,
  },
  {
    label: "Fashion",
    id: 2,
  },
  {
    label: "News",
    id: 3,
  },
  {
    label: "Cooking",
    id: 4,
  },
  {
    label: "Education",
    id: 5,
  }
];

function tabScreen({ navigation, route }) {
  const [posts, setPosts] = useState([]);
  const [error, setError] = useState(false);
  const [loading, setLoading] = useState(false);
  const [page, setPage] = useState(0);
  const [label, setLabel] = useState(categories[0]?.label);
  const [currentCategoryId, setCurrentCategoryId] = useState(1);

  const loadPosts = async (id, page = 0) => {
    setLoading(true);
    const response = await getCategoryPostsAPI(id, page)
    setLoading(false);
    if (refreshing) setRefreshing(false);
    if (!response.ok) return setError(true);
    setError(false);
    if (page === 0) {
      setPosts(response.data)
    } else {
      setPosts([...posts, ...response.data]);
    }
  };

  useEffect(() => {
    if (page > 0)
      loadPosts(currentCategoryId, page);
  }, [page]);

  useEffect(() => {
    setPage(0);
    loadPosts(currentCategoryId, 0);
  }, [currentCategoryId])

  const handleLoadMore = () => {
    setPage(page + 1);
  };

  const setLabelFilter = label => {
    setLabel(label);
  };

  const toggleBrands = (categoryId) => {
    setCurrentCategoryId(categoryId);
  };

  const postsToBeDisplayed = () => posts.filter(post => post.categoryId === currentCategoryId);

  return (
    <>
      <ScrollView
        horizontal
        showsHorizontalScrollIndicator={false}
      >
        {categories.map(e => (
          <TouchableOpacity
            key={e.id}
            onPress={() => {
              toggleBrands(e.id);
              setLabelFilter(e.label);
            }}
            selected={e.id === currentCategoryId}
          >
            <Text>{e.label}</Text>
          </TouchableOpacity>
        ))}
      </ScrollView>

      <FlatList
        data={postsToBeDisplayed()}
        renderItem={({ item, index }) => (
          <Card
            title={item.title}
            subTitle={item.subTitle}
            onPress={() => navigation.navigate(routes.POST_DETAILS, { post: item, index })}
          />
        )}
        onEndReached={handleLoadMore}
        onEndReachedThreshold={0.000001}
        initialNumToRender={10}
        keyExtractor={(post) => post.id.toString()}
      />
    </>
  )
};


但是,如果您想实现选项卡功能,我建议您使用react-native-tab-view。这将使整个过程变得容易得多。


推荐阅读