在我的Next.js模块中,我有一个声明如下的表单:

<form onSubmit = {() => {
async() => await getCertificate(id)
.then(async resp => await resp.json())
.then(data => console.log(data))
.catch(err => console.error(err))
console.log("getCertificate completed")
}}>

函数getCertificate()在相同的.tsx文件中定义为:

async function getCertificate(id: string) : Promise<Response> {
  console.log("in getCertificate")
  const resp = await fetch(`${serverUri}/certs/${id}`)
  console.log(`Response data: ${await resp.json()}`)
  return resp
}

似乎getCertificate()号根本就没有被呼叫. 当我的onSubmit处理程序中的final console.log("getCertificate completed")正确执行时,getCertificate()中的console.log()条语句都没有执行.

没有错误被抛出或记录到控制台. 控制台中唯一出现的(除了getCertificate completed)是Navigated to http://localhost:3000/?certId=my_cert_id.

你知道它为什么会这样吗?

(唯一需要注意的是,我的.tsx文件使用'use client'装饰,因为我正在使用客户端库来实现某些其他功能,并且我的表单定义在export default functionreturn语句中.除了getCertificates()没有被击中之外,其他的都可以正常工作).

推荐答案

可能的解决方案

如果唯一的问题是让getCertificate人被执行,那么你可以try 这样做:

import React, { useState } from "react";

const serverUri = "http://myserver.com";

export default function Certificate() {
  const [id, setId] = useState("");
  async function getCertificate(id: string): Promise<Response> {
    console.log("in getCertificate");
    const resp = await fetch(`${serverUri}/certs/${id}`);
    console.log(`Response data: ${await resp.json()}`);
    return resp;
  }
  return (
    <form onSubmit={async (event: any) => {
      event.preventDefault();
      try {
        const response = await getCertificate(id);
        const data = await response.json();
        console.log(data);
      } catch (err) {
        console.error(err);
      }
      console.log("getCertificate completed");
    }}>
      <label>
        Certificate ID:
        <input type="text" value={id} onChange={e => setId(e.target.value)} />
      </label>
      <button type="submit">Submit</button>
    </form>
  );
}

execution result

正如你在屏幕截图上看到的,in getCertificate被打印到控制台.

它之所以不能执行

让我们仔细看看原始函数:

() => {
    async() => await getCertificate(id)
    .then(async resp => await resp.json())
    .then(data => console.log(data))
    .catch(err => console.error(err))
    console.log("getCertificate completed")
}

正如您在这里看到的,您在这里只定义了一个匿名的异步箭头函数(没有将该函数赋给任何变量,因此该函数永远不会被调用),然后执行console.log.所以console.log是唯一真正被执行的东西.

此外,在呼叫getCertificate之前添加await,这不是必需的,可能会导致额外的混淆.

让我们简化一下这行代码

async() => await getCertificate(id)
.then(async resp => await resp.json())
.then(data => console.log(data))
.catch(err => console.error(err))

因此,首先我们将重新格式化代码以查看其 struct :

async() => { 
    await getCertificate(id)
        .then(async resp => await resp.json())
        .then(data => console.log(data))
        .catch(err => console.error(err))
}

然后,我们删除不必要的函数定义:

await getCertificate(id)
    .then(async resp => await resp.json())
    .then(data => console.log(data))
    .catch(err => console.error(err))

然后我们将删除不必要的await:

getCertificate(id)
    .then(async resp => await resp.json())
    .then(data => console.log(data))
    .catch(err => console.error(err))

另一种解决方案

因此,使用上一节中的变换,我们可以得到另一种定义整个函数的方法.

(event: any) => {
    event.preventDefault();
    getCertificate(id)
        .then(async resp => await resp.json())
        .then(data => console.log(data))
        .then(() => console.log("getCertificate completed with no errors"))
        .catch(err => console.error(err))
        .then(() => console.log("getCertificate completed with errors"))
}

附注:

请注意,两种解决方案中的event.preventDefault()都将阻止表单数据的实际传输,并强制处理JS中的所有内容.它是可选的,可以省略.

Javascript相关问答推荐

使用expressjs加载Nuxt版本=3.9.0(自定义服务器)

JavaScript替换子 node 导致它们更改为[对象HTMLTable SectionElement]

Webpack将懒惰加载的模块放入主块中

try 在addEventHandler内设置表单的文件输入.值=空

响应式JS DataTable中的Bootstrap 5弹出程序无法正常工作

如何按预期聚合SON数据?

如何将拖放功能添加到我已自定义为图像的文件输入HTML标签中?

仅圆角的甜甜圈图表

react/redux中的formData在expressjs中返回未定义的req.params.id

从WooCommerce Checkout Country字段重新排序国家,保持国家同步

jQuery s data()[storage object]在vanilla JavaScript中?'

如何调用名称在字符串中的实例方法?

为什么Mutations 观察器用微任务队列而不是macrotask队列处理?

为什么我的getAsFile()方法返回空?

Next.js中的服务器端组件列表筛选

匹配一个或多个可选重复的特定模式

FileReader()不能处理Firefox和GiB文件

在Java脚本中录制视频后看不到曲目

Pevent触发material 用户界面数据网格中的自动保存

如何在下一个js中更改每个标记APEXCHARTS图表的 colored颜色