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

NextJS:如何从外部组件修改getStaticProps的type参数并重获数据

问题分析与解决方案

你当前的问题核心在于 getStaticProps 是在构建阶段执行的静态数据获取逻辑,生成页面后就不会再触发,无法响应客户端的下拉筛选交互。加上直接在客户端调用 loadListings 会触发CORS限制,所以需要通过「Next.js API路由做代理 + 客户端动态数据获取」的方式解决。

步骤1:创建API路由作为代理

在 pages/api 目录下新建 listings.js,用它来中转请求——服务器端调用外部API不会受CORS限制:

// pages/api/listings.js
import { loadListings } from '../../path/to/your/loadListings'

export default async function handler(req, res) {
  const { type = 0, limit = 20 } = req.query
  try {
    // 调用原loadListings函数,参数从请求query中获取
    const data = await loadListings(parseInt(type), parseInt(limit))
    res.status(200).json(data)
  } catch (err) {
    res.status(500).json({ error: '获取列表数据失败' })
  }
}

步骤2:修改Home页面,实现动态筛选逻辑

移除原有的 getStaticProps,改用客户端状态管理+API请求来响应下拉筛选的变化,这里提供两种实现方式:

方式一:原生React Hooks实现

// pages/index.js
import { useState, useEffect } from 'react'
import Listings from '../components/Listings'
import Page from '../components/Page'

export default function Home() {
  // 保存当前选中的类型
  const [selectedType, setSelectedType] = useState(0)
  const [listData, setListData] = useState([])
  const [isLoading, setIsLoading] = useState(true)

  // 当selectedType变化时,重新请求数据
  useEffect(() => {
    const fetchListData = async () => {
      setIsLoading(true)
      try {
        const res = await fetch(`/api/listings?type=${selectedType}&limit=20`)
        const data = await res.json()
        setListData(data)
      } catch (err) {
        console.error('数据请求失败:', err)
      } finally {
        setIsLoading(false)
      }
    }
    fetchListData()
  }, [selectedType])

  // 下拉框变化事件处理
  const handleTypeChange = (e) => {
    setSelectedType(parseInt(e.target.value))
  }

  return (
    <Page>
      <div>
        {/* 下拉筛选组件 */}
        <select value={selectedType} onChange={handleTypeChange}>
          <option value={0}>类型0</option>
          <option value={1}>类型1</option>
          <option value={2}>类型2</option>
        </select>

        {isLoading ? (
          <p>加载中...</p>
        ) : (
          <Listings data={listData} />
        )}
      </div>
    </Page>
  )
}

方式二:用SWR简化数据获取(推荐)

SWR会自动处理缓存、重新请求和加载状态,代码更简洁:

// pages/index.js
import { useState } from 'react'
import useSWR from 'swr'
import Listings from '../components/Listings'
import Page from '../components/Page'

// 定义通用fetch函数
const fetcher = async (url) => {
  const res = await fetch(url)
  return res.json()
}

export default function Home() {
  const [selectedType, setSelectedType] = useState(0)
  // SWR会监听selectedType变化,自动重新请求
  const { data: listData, error, isLoading } = useSWR(
    `/api/listings?type=${selectedType}&limit=20`,
    fetcher
  )

  const handleTypeChange = (e) => {
    setSelectedType(parseInt(e.target.value))
  }

  if (error) return <div>数据加载失败</div>
  if (isLoading) return <div>加载中...</div>

  return (
    <Page>
      <div>
        <select value={selectedType} onChange={handleTypeChange}>
          <option value={0}>类型0</option>
          <option value={1}>类型1</option>
          <option value={2}>类型2</option>
        </select>
        <Listings data={listData} />
      </div>
    </Page>
  )
}

补充说明

如果需要首屏加载更快,可以保留 getStaticProps 获取初始类型(type=0)的数据,作为页面的初始渲染内容,后续筛选再用客户端请求更新数据——这样兼顾静态生成的性能和动态交互的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 20:45:26