【问题标题】:What's the best way to fetch data on form submit in Next.js?在 Next.js 中获取表单提交数据的最佳方法是什么?
【发布时间】:2021-08-03 11:38:47
【问题描述】:

我可以使用下面的代码和Metadata-scaper 在硬编码时成功地从 url 中检索元数据。但是我将如何允许用户使用文本输入输入链接并在表单提交时获取元数据?

我对将数据传递给 getStaticProps 感到困惑。非常感谢您的帮助。

import Head from 'next/head'
import { useState } from 'react';
import styles from '../styles/Home.module.css'
import getMetaData from 'metadata-scraper'

export async function getStaticProps(name) {
  const url = "http://www.bbc.com"
  const data = await getMetaData(url)
  var urlData = JSON.stringify(data);

  if (!urlData) {
    return {
      notFound: true,
    }
  }

  return {
    props: { urlData }, // will be passed to the page component as props
  }
}

export default function Home(urlData) {
  const [name, setName] = useState('');

  const handleSubmit = e => {
    e.preventDefault();
    const data = {
      name,
    };
    getStaticProps(name)
    console.log(data);
  };

  const myData = JSON.parse(urlData.urlData)

  return (
    <div>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <main>
        <form onSubmit={handleSubmit} className={styles.form}>
          <label htmlFor="name">Name:</label>
          <input
            id="name"
            type="text"
            onChange={e => setName(e.target.value)}
          />

          <button type="submit">Send</button>
        </form>
      </main>
      {console.log(myData.title)}
      <table>
        <tr>
          <th>title</th>
          <th>Provider</th>
          <th>Author</th>
          <th>url</th>
          <th>Language</th>
          <th>Published</th>
        </tr>
        <tr>
          <td>{myData.title}</td>
          <td>{myData.provider}</td>
          <td>{myData.author}</td>
          <td>{myData.url}</td>
          <td>{myData.language}</td>
          <td>{myData.published}</td>
        </tr>

      </table>
    </div>
  );
}

2021 年 3 月 8 日更新 - 格林威治标准时间 15:35

我已经像这样将 API 路由分离到 api/meta.js,但是如何从那里传递表单中的链接?

import getMetaData from 'metadata-scraper'

export default async function handler(req, res) {
  try {
    const url = 'www.bbc.com'
    res.statusCode = 200;
    const data = await getMetaData(url)
    res.end(JSON.stringify(data));
    console.log(data)
    
  }
  catch (error) {
    res.json(error);
    res.status(405).end();
  }
}

更新 index.js

import Head from 'next/head'
import { useState } from 'react';
import styles from '../styles/Home.module.css'
import useSWR from 'swr'

export default function Home() {

  const { data } = useSWR('/api/meta', fetch)
  const [name, setName] = useState('');
  
  const handleSubmit = e => {
    e.preventDefault();
    fetch('/api/meta', {
      method: 'post',
      body: JSON.stringify({
        name: name,
      })
    })
  };

  return (
    <div>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <main>
        <form onSubmit={handleSubmit} className={styles.form}>
          <label htmlFor="name">Name:</label>
          <input
            id="name"
            type="text"
            onChange={e => setName(e.target.value)}
          />

          <button type="submit">Send</button>
        </form>
      </main>
    </div>
  );
}

【问题讨论】:

    标签: javascript reactjs next.js


    【解决方案1】:

    你在这里混淆了一些不正确的东西。

    getStaticProps 永远不应该被手动调用。它在构建过程中的静态站点生成 (SSG) 步骤中由 nextjs 调用,并且每个页面仅调用一次(除非这些页面是通过 revalidate: 10 生成的)。

    不仅如此,您的表单提交还应使用您要提交的数据调用后端 API。在这种情况下,您在这里混淆了客户端和服务器端的概念。该表单提交将在客户端执行,而 getStaticProps 将永远不会在客户端执行。所以你需要一些东西来调用你的后端 API。

    Nextjs 有一个你可以使用的内置 API,我建议你遵循他们的指南:https://nextjs.org/docs/api-routes/introduction

    getStaticProps 应该只在页面第一次渲染时被调用一次,之后如果你想为页面添加功能,特别是客户端,它应该只在 react 组件中完成。

    // this will execute client side
    
    const Home = (props) => {
      const [formfield1, setFormfield1] = useState('')
    
      const submit = () => {
        fetch('https://example.com/api', {
          method: 'post',
          body: JSON.stringify({
            formfield1: formfield1,
          })
        }
      }
    
      return <form onSubmit={(e) => {e.preventDefault(); submit()}>
        // form stuff here
      </form>
    }
    
    ...
    
    // this will only ever get executed on page generation server side, not ever on form submit
    
    export const getStaticProps = async () => {
      //
    }
    

    然后你想在 nextjs 中创建一个名为“api”的目录并将你的表单提交代码放在那里,这样你就可以从客户端调用你的后端 API。

    【讨论】:

    • 感谢您让我走上正轨。我已根据您的建议更新了问题,但仍在努力让其相互交谈。
    猜你喜欢
    • 2013-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-03
    • 2020-01-16
    • 1970-01-01
    • 2017-07-23
    • 1970-01-01
    相关资源
    最近更新 更多