Next.js中下拉值变更时如何修改API请求并传递参数到index.tsx
问题核心原因
getServerSideProps 仅在页面首次请求时在服务端执行,仅用于生成首次渲染的页面内容,后续用户在客户端下拉选择国家、年份属于前端交互,无法直接将参数反向传递给已经执行完毕的服务端逻辑,需要调整数据获取方案。
方案1:URL查询参数 + getServerSideProps(推荐)
该方案支持刷新页面保留选择状态、URL可分享,同时保留服务端渲染的优势。
1. 修改index.tsx
import type { NextPage, GetServerSideProps } from 'next' import { GetAllHolidays, GetAllHolidaysData } from './api' // 按实际路径调整 import Holidays from './Holiday' const Home: NextPage<{ holidays: GetAllHolidaysData, initialCountry: string, initialYear: number }> = ({ holidays, initialCountry, initialYear }) => { return ( <> <Holidays holidays={holidays} initialCountry={initialCountry} initialYear={initialYear} /> </> ); }; export const getServerSideProps: GetServerSideProps = async (context) => { // 从URL查询参数取值,设置默认值 const country = (context.query.country as string) || "ro"; const year = Number(context.query.year) || 2024; let holidays: GetAllHolidaysData = {} as GetAllHolidaysData; try { const { data } = await GetAllHolidays(country, year); holidays = data; } catch (error) { console.log(error); } return { props: { holidays, initialCountry: country, initialYear: year }, }; }; export default Home;
2. 修改Holiday.tsx
import { useState } from 'react' import { useRouter } from 'next/router' import { GetAllHolidays, GetAllHolidaysData } from './api' // 按实际路径调整 // 按实际的组件props定义调整类型 interface HolidaysProps { holidays: GetAllHolidaysData initialCountry: string initialYear: number } const Holidays = ({ holidays, initialCountry, initialYear }: HolidaysProps) => { const router = useRouter() // 初始值用服务端传回的参数 const [selectedYear, setSelectedYear] = useState(initialYear); // 根据初始国家代码匹配下拉选项 const [selectedCountry, setSelectedCountry] = useState(() => { return countries.find(item => item.value === initialCountry) || countries[169] }); const countryChangeHandler = async (e) => { setSelectedCountry(e); // 更新URL参数,触发getServerSideProps重新执行拉取新数据 await router.push({ pathname: '/', query: { country: e.value, year: selectedYear } }) }; const yearChangeHandler = async (e) => { setSelectedYear(e.value); await router.push({ pathname: '/', query: { country: selectedCountry.value, year: e.value } }) }; // 剩余渲染逻辑不变 } export default Holidays
方案2:纯客户端数据获取
适合不需要SEO、不需要分享页面的场景,逻辑更简单。
1. 修改index.tsx
import type { NextPage } from 'next' import { useState, useEffect } from 'react' import { GetAllHolidays, GetAllHolidaysData } from './api' // 按实际路径调整 import Holidays from './Holiday' const Home: NextPage = () => { const [holidays, setHolidays] = useState<GetAllHolidaysData>({} as GetAllHolidaysData) // 首次加载拉取默认数据 useEffect(() => { const fetchDefault = async () => { try { const { data } = await GetAllHolidays('ro', 2024) setHolidays(data) } catch (err) { console.log(err) } } fetchDefault() }, []) return ( <> <Holidays holidays={holidays} setHolidays={setHolidays} /> </> ); }; export default Home;
2. 修改Holiday.tsx
import { useState } from 'react' import { GetAllHolidays, GetAllHolidaysData } from './api' // 按实际路径调整 // 按实际的组件props定义调整类型 interface HolidaysProps { holidays: GetAllHolidaysData setHolidays: React.Dispatch<React.SetStateAction<GetAllHolidaysData>> } const Holidays = ({ holidays, setHolidays }: HolidaysProps) => { const [selectedYear, setSelectedYear] = useState(currentYear); const [selectedCountry, setSelectedCountry] = useState(countries[169]); const countryChangeHandler = async (e) => { setSelectedCountry(e); try { const { data } = await GetAllHolidays(e.value, selectedYear) setHolidays(data) } catch (err) { console.log(err) } }; const yearChangeHandler = async (e) => { setSelectedYear(e.value); try { const { data } = await GetAllHolidays(selectedCountry.value, e.value) setHolidays(data) } catch (err) { console.log(err) } }; // 剩余渲染逻辑不变 } export default Holidays
内容的提问来源于stack exchange,提问作者hanu
相关产品推荐
相关产品推荐

