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

NextJS如何通过React Context将输入框值传递到getStaticProps

问题1:核心错误原因
  • 首先,getStaticProps 是 Next.js 服务端构建/预编译阶段运行的纯服务端逻辑,完全运行在 Node.js 环境,不会访问到客户端侧的 React Context。Context 是客户端 React 运行时的状态管理机制,两者的执行生命周期完全隔离。
  • 无效 Hook 报错的直接原因是你大概率在 getStaticProps 内直接调用了 useContext 这类 React Hook。Hook 只能在 React 函数组件、自定义 Hook 的顶层调用,在服务端静态生成函数内调用 Hook 本身就违反 Hook 调用规则。
  • 额外说明:哪怕替换为 getServerSideProps 也无法拿到 Context 状态,服务端渲染的请求处理阶段也不存在客户端的 Context 实例。
问题2:可运行实现方案

首先明确:无法将Context中存储的搜索关键词传入getStaticProps的请求URL。getStaticProps在项目构建阶段(或者配置了增量再生的话是后台预编译阶段)就已经执行完成生成静态HTML,此时用户还没有访问页面、更没有输入搜索内容,完全不可能拿到客户端后续产生的Context状态。
可以选择以下两种适配场景的实现方案:

方案1:客户端侧请求(最适配搜索场景)

放弃用 getStaticProps 拉取搜索结果,改为在搜索结果页组件内读取 Context 存储的关键词,客户端发起请求拉取数据:

Context 定义代码

// contexts/SearchContext.js
import { createContext, useContext, useState } from 'react';

const SearchContext = createContext();

export function SearchProvider({ children }) {
  const [searchKeyword, setSearchKeyword] = useState('');
  return (
    <SearchContext.Provider value={{ searchKeyword, setSearchKeyword }}>
      {children}
    </SearchContext.Provider>
  );
}

export function useSearch() {
  return useContext(SearchContext);
}

SearchBar 组件代码

// components/SearchBar.js
import { useRouter } from 'next/router';
import { useSearch } from '../contexts/SearchContext';

export default function SearchBar() {
  const { setSearchKeyword } = useSearch();
  const router = useRouter();

  const handleSubmit = (e) => {
    e.preventDefault();
    const keyword = e.target.searchInput.value.trim();
    if (!keyword) return;
    setSearchKeyword(keyword);
    // 跳转到搜索结果页
    router.push('/searchResults');
  };

  return (
    <form onSubmit={handleSubmit}>
      <input name="searchInput" placeholder="输入搜索内容" />
      <button type="submit">搜索</button>
    </form>
  );
}

_app.js 全局注入Provider

// pages/_app.js
import { SearchProvider } from '../contexts/SearchContext';
import '../styles/globals.css';

export default function MyApp({ Component, pageProps }) {
  return (
    <SearchProvider>
      <Component {...pageProps} />
    </SearchProvider>
  );
}

搜索结果页代码

// pages/searchResults.js
import { useEffect, useState } from 'react';
import { useSearch } from '../contexts/SearchContext';

export default function SearchResults() {
  const { searchKeyword } = useSearch();
  const [results, setResults] = useState([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    if (!searchKeyword) return;
    // 客户端侧发起请求拉取搜索结果
    const fetchResults = async () => {
      setLoading(true);
      const res = await fetch(`/api/search?keyword=${encodeURIComponent(searchKeyword)}`);
      const data = await res.json();
      setResults(data);
      setLoading(false);
    };
    fetchResults();
  }, [searchKeyword]);

  if (loading) return <div>加载中...</div>;
  if (!searchKeyword) return <div>请输入搜索内容</div>;

  return (
    <div>
      <h1>搜索结果:{searchKeyword}</h1>
      {results.map((item, idx) => (
        <div key={idx}>{item.title}</div>
      ))}
    </div>
  );
}

方案2:URL参数传递(支持服务端拉数据)

如果需要服务端拉取搜索数据,不要用 Context 传递关键词,直接将关键词放到 URL 参数中,用 getServerSideProps 读取参数拉取数据:

调整SearchBar提交逻辑

// components/SearchBar.js 调整handleSubmit部分
const handleSubmit = (e) => {
  e.preventDefault();
  const keyword = e.target.searchInput.value.trim();
  if (!keyword) return;
  router.push(`/searchResults?keyword=${encodeURIComponent(keyword)}`);
};

搜索结果页服务端拉取代码

// pages/searchResults.js
export default function SearchResults({ results, keyword }) {
  return (
    <div>
      <h1>搜索结果:{keyword}</h1>
      {results.map((item, idx) => (
        <div key={idx}>{item.title}</div>
      ))}
    </div>
  );
}

export async function getServerSideProps(context) {
  const keyword = context.query.keyword || '';
  // 服务端直接发起请求拉取数据
  const res = await fetch(`你的后端接口地址?keyword=${encodeURIComponent(keyword)}`);
  const results = await res.json();

  return {
    props: {
      results,
      keyword
    }
  };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 16:36:04