0

我是 NextJS 和 React 的新手,所以我请求您的原谅。我想知道如何通过反应上下文 api 将用户写入的文本从输入字段(标题内部)传递到特定页面的 getStaticProbs 函数中。我尝试了以下来源,但它不起作用 - 它抛出一个错误,我的构建方式导致无效的钩子调用。

这是我的上下文来源:

import React, { createContext, useState } from 'react';

export const SearchContext = createContext();

export const SearchProvider = ({ children }) => {
  const [keyword, setKeyword] = useState('');

  return (
    <SearchContext.Provider
      value={{
        keyword,
        setKeyword,
      }}
    >
      {children}
    </SearchContext.Provider>
  );
};

获取 SearchBar.js 的写入字符串:

import React, { useContext, useState } from 'react';
import { useRouter } from 'next/router';
import Image from 'next/image';
import loupe from '../public/images/loupe.png';
import { SearchContext } from '../lib/searchCtx';

const SearchBar = () => {
  const search = useContext(SearchContext);

  const router = useRouter();

  const submitAction = (e) => {
    e.preventDefault();
    router.push(`/searchResults`);
  };

  return (
    <div className={styles.searchBar}>
      <input
        type='text'
        placeholder='Suche...'
        onChange={(e) => search.setKeyword(e.target.value)}
      />
      <button className={styles.searchBtn} type='submit' onClick={submitAction}>
        <Image src={loupe} alt='' />
      </button>
    </div>
  );
};

export default SearchBar;

并将其传递给 _app.js:

import Header from '../components/Header';
import Footer from '../components/Footer';
import { SearchProvider } from '../lib/searchCtx';

function MyApp({ Component, pageProps }) {

    return (
      <>
        <SearchProvider>
          <Header />
          <Component {...pageProps} />
        </SearchProvider>
        <Footer />
      </>
    );
  }
}

export default MyApp;

将值放入 searchResults.js 的 getStaticProbs 中:

import { useEffect, useState, useContext } from 'react';
import { fetchData } from '../lib/utils';
import styles from '../styles/Playlist.module.scss';
import Image from 'next/image';
import { SearchContext } from '../lib/searchCtx';

export default function SearchResults({ videos }) {
  console.log(videos);

  const sortedVids = videos
    .sort((a, b) =>
      Number(
        new Date(b.snippet.videoPublishedAt) -
          Number(new Date(a.snippet.videoPublishedAt))
      )
    )

  return (
    <>
      <div className={`${styles.playlist_container} ${styles.search}`}>
            <h1>Search results</h1>      
          {sortedVids
            .map((vid, id) => {
              return (
                  <div className={styles.clip_container}>
                    <Image
                      className={styles.thumbnails}
                      src={vid.snippet.thumbnails.medium.url}
                      layout='fill'
                      objectFit='cover'
                      alt={vid.snippet.title}
                    />
                  </div>
                  <div className={styles.details_container}>
                    <h3>{vid.snippet.title}</h3>
                  </div>
              );
            })}
      </div>
    </>
  );
}

export async function getStaticProps() {
  const search = useContext(SearchContext);

  const { YOUTUBE_KEY } = process.env;
  const uploadsURL = `https://youtube.googleapis.com/youtube/v3/search?part=snippet&channelId=UCbqKKcML7P4b4BDhaqdh_DA&maxResults=50&key=${YOUTUBE_KEY}&q=${search.keyword}`;

  async function getData() {
    const uploadsData = fetchData(uploadsURL);

    return {
      videos: await uploadsData,
    };
  }

  const { videos } = await getData();
  return {
    revalidate: 86400,
    props: {
      videos: videos.items,
    },
  };
}

你会帮助我 1) 告诉我我所做的主要失败和 2) 为我提供工作来源吗?我如何才能将 SearchContext 中的关键字获取到 uploadsURL(在 getStaticProbs 内部),还是不可能?提前致谢!!

4

1 回答 1

0

您可以在页面文件夹下创建一个动态页面,一个名为 index.js 和一个名为 [slug].js (都在一个文件夹下) 在索引页面中,您可以进行正常的搜索输入,当用户提交查询时,您可以做

<a
  onClick={() =>
   router
    .push(`/movies/${search.keyword}`)
    .then(() => window.scrollTo(0, 0))}>
   search
 </a>

在您的 [slug].js 页面中,您可以像这样检索该信息

export async function getServerSideProps(pageContext) {
  const pageQuery = pageContext.query.slug;
  const apiCall= await fetch(
    ``https://youtube.googleapis.com/youtube/v3/search?part=snippet&channelId=UCbqKKcML7P4b4BDhaqdh_DA&maxResults=50&key=${YOUTUBE_KEY}&q=${pageQuery}`
  );

  const results = await apiCall.json();

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

我不知道这是否对您有用,但这是一个解决方案

于 2021-09-06T15:45:24.907 回答