如何用React Router的Await实现点击加载更多国家数据的组件渲染
问题描述
需求为实现国家数据分批加载:首次加载8条数据,点击「显示更多」按钮时加载下8条,已加载数据需保留在页面中(类无限滚动,改用按钮触发),API地址为https://restcountries.com/v3.1/all。现有代码尝试通过useState及拆分Suspense/Await组件实现,但未达到预期效果。
解决方案
核心思路:由于目标API不支持分页参数,先获取全部数据后,通过状态控制渲染的条目数量范围,同时处理数据加载完成后的按钮隐藏逻辑。
修改后的完整代码:
import React, { Suspense, useState } from "react"; import { getAllCountries } from "../api/api"; import { defer, useLoaderData, Await } from "react-router-dom"; import CountryCard from "../components/CountryCard"; import Button from "../components/Button"; import ShowMoreIcon from "../components/Icons/ShowMoreIcon"; import Loading from "../components/Loading"; export const loader = async () => { const countries = getAllCountries(); return defer({ countries }); }; const NUM_TO_ADD = 8; const CountriesPage = () => { const { countries } = useLoaderData(); // 用visibleCount控制显示的条目总数,初始为8 const [visibleCount, setVisibleCount] = useState(NUM_TO_ADD); const showMoreHandler = () => { setVisibleCount(prev => prev + NUM_TO_ADD); }; return ( <main className="px-16 xl:px-0 xl:mx-auto max-w-7xl"> <div className="grid grid-cols-[repeat(auto-fit,minmax(250px,1fr))] gap-6 lg:gap-12 mb-12"> <Suspense fallback={<Loading />}> <Await resolve={countries}> {(data) => { // 截取前visibleCount条数据渲染 const visibleCountries = data.slice(0, visibleCount); return visibleCountries.map((country) => ( <CountryCard key={country.name.common} countryCapital={country.capital} countryFlag={country.flags.png} countryPopulation={country.population} countryRegion={country.region} countryId={country.cca3} countryName={country.name.common} /> )); }} </Await> </Suspense> </div> {/* 仅当显示数量小于总数据量时,显示「显示更多」按钮 */} <Suspense fallback={<></>}> <Await resolve={countries}> {(data) => ( visibleCount < data.length && ( <Button onClick={showMoreHandler} className="mx-auto flex items-center"> <ShowMoreIcon /> Show More </Button> ) )} </Await> </Suspense> </main> ); }; export default CountriesPage;
关键改动说明
- 将
start/end状态替换为visibleCount,更直观控制显示的条目总数,避免范围计算出错 - 在
Await回调中通过slice(0, visibleCount)截取需渲染的数据,确保每次仅显示指定数量的条目 - 为「显示更多」按钮添加判断逻辑:仅当
visibleCount小于总数据量时才显示,避免数据加载完成后按钮仍存在 - 调整
Loading组件的导入位置,符合代码规范
补充说明
若后续API支持分页参数(如page/limit),可优化为点击按钮时请求下一页数据,将新数据追加到已加载列表中,进一步节省带宽。
内容的提问来源于stack exchange,提问作者Elyael19
相关产品推荐
相关产品推荐

