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

如何在Next.js中从组件向getServerSideProps()传递Props?

问题分析

首先得明确一个关键:getServerSideProps 是在服务器端运行的预渲染函数,它会在组件渲染之前就执行完毕。而你组件里的 number 是客户端的 useState 状态,只有当页面在客户端渲染完成后,用户交互(比如修改输入框)才会改变这个值。所以两者的执行时机完全不重叠,没法直接把组件里的 url 传给 getServerSideProps。

接下来分两种常见场景给你具体的解决方案:


场景1:number 来自 URL 参数(比如路由传参)

如果你的 number 是通过 URL 传递的(比如用户访问 /home?number=1234567890),那可以直接在 getServerSideProps 里从上下文的 query 中获取参数,再构造请求 URL:

import { useState } from 'react';
import Head from 'next/head';

export default function Home({ data, initialNumber }) {
  // 把从服务端拿到的number作为初始state
  const [number, setNumber] = useState(initialNumber || "9999999999");

  return (
    <div>
      <Head>
        <title>Numverify</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <main>
        <div className="h-16 dark:bg-gray-900 bg-white shadow-md flex justify-center items-center">
          <span className="text-gradient font-bold text-xl">NumVerify</span>
        </div>
        {/* 可以加输入框让用户修改号码 */}
        <input 
          type="text" 
          value={number} 
          onChange={(e) => setNumber(e.target.value)}
          placeholder="输入手机号"
          className="mt-4 p-2 border rounded"
        />
        {/* 展示服务端返回的数据 */}
        {data && (
          <div className="mt-4 p-4 border rounded">
            <p>号码有效性:{data.valid ? "有效" : "无效"}</p>
            <p>国家代码:{data.country_code}</p>
          </div>
        )}
      </main>
    </div>
  );
}

export async function getServerSideProps(context) {
  // 从URL的query参数里取number,默认值设为9999999999
  const { number = "9999999999" } = context.query;
  const url = `http://apilayer.net/api/validate?access_key=e52d69f119348057d68ec090d2d10978&number=${number}`;
  
  const res = await fetch(url);
  const data = await res.json();
  
  return {
    props: { 
      data,
      initialNumber: number // 把number传给组件当初始值
    },
  };
}

这种方式适合页面加载时就需要根据URL参数获取数据的场景。


场景2:number 是用户在页面输入的客户端交互值

如果 number 是用户手动输入的,那这时候属于客户端交互,getServerSideProps 早就执行完了,没法再用它请求数据。这时候应该在客户端用 fetch 配合 useEffect,监听状态变化时发起请求:

import { useState, useEffect } from 'react';
import Head from 'next/head';

export default function Home() {
  const [number, setNumber] = useState("9999999999");
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);

  // 当number变化时,发起客户端请求
  useEffect(() => {
    const fetchNumberData = async () => {
      setLoading(true);
      const url = `http://apilayer.net/api/validate?access_key=e52d69f119348057d68ec090d2d10978&number=${number}`;
      try {
        const res = await fetch(url);
        const result = await res.json();
        setData(result);
      } catch (err) {
        console.error("请求出错:", err);
      } finally {
        setLoading(false);
      }
    };

    fetchNumberData();
  }, [number]); // 依赖number变化触发请求

  return (
    <div>
      <Head>
        <title>Numverify</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <main>
        <div className="h-16 dark:bg-gray-900 bg-white shadow-md flex justify-center items-center">
          <span className="text-gradient font-bold text-xl">NumVerify</span>
        </div>
        <input 
          type="text" 
          value={number} 
          onChange={(e) => setNumber(e.target.value)}
          placeholder="输入手机号"
          className="mt-4 p-2 border rounded"
        />
        {loading && <p className="mt-4">加载中...</p>}
        {data && (
          <div className="mt-4 p-4 border rounded">
            <p>号码有效性:{data.valid ? "有效" : "无效"}</p>
            <p>国家:{data.country_name}</p>
            <p>运营商:{data.carrier}</p>
          </div>
        )}
      </main>
    </div>
  );
}

// 这里不需要getServerSideProps了,数据全部在客户端请求

这种方式适合用户交互后动态获取数据的场景,完全在客户端处理请求流程。


总结一下

  • 页面初始化时需根据URL参数获取数据:用 getServerSideProps 从 context.query 拿参数。
  • 用户交互后动态获取数据:在客户端用 useEffect 监听状态变化,发起请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 23:34:09