next.js 我不能理解状态中的错误,如何在Typescript中使用此错误

1bqhqjot  于 2023-04-20  发布在  TypeScript
关注(0)|答案(1)|浏览(107)

我想通过Nodemailer,TypeScript和NextJS发送邮件。状态组件的contact.tsx文件中有一个错误。如何修复错误?使用setform可能会导致表单状态错误。我是打字脚本的初学者,无法找到任何解决方案。如果有人能解决这个问题,我会非常感激。
contact.tsx文件用于页面。

import React, { useState } from 'react';
export default function Contact() {

  const [inputs, setInputs] = useState({
    fname: '',
    lname: '',
    email: '',
    message: ''
  });

  const [form, setForm] = useState('')
  const handleChange = (e) => {
        setInputs((prev) => ({
            ...prev,
            [e.target.id]: e.target.value,
        }))
    }

  const onSubmitForm = async (e) => {
        e.preventDefault()

        if (inputs.fname && inputs.email && inputs.phone && inputs.message) {
            setForm({ state: 'loading' })
            try {
                const res = await fetch(`api/contact`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify(inputs),
                })

                const { error } = await res.json()

                if (error) {
                    setForm({
                        state: 'error',
                        message: error,
                    })
                    return
                }

                setForm({
                    state: 'success',
                    message: 'Your message was sent successfully.',
                })
                setInputs({
                    fname: '',
                    lname: '',
                    email: '',
                    message: '',
                })
            } catch (error) {
                setForm({
                    state: 'error',
                    message: 'Something went wrong',
                })
            }
        }
  }

  return (
    <form onSubmit={(e) => onSubmitForm(e)}>
        <input
        type="text"
        id="fname"
        value={inputs.fname}
        onChange={handleChange}
        className="form-control"
        placeholder="First Name"
        required
        />

        <input
        type="text"
        id="lname"
        value={inputs.fname}
        onChange={handleChange}
        className="form-control"
        placeholder="Last Name"
        required
        />

        <input
        type="email"
        id="email"
        value={inputs.email}
        onChange={handleChange}
        className="form-control"
        placeholder="Email"
        required
        />

        <textarea
        id="message"
        value={inputs.message}
        onChange={handleChange}
        rows={4}
        className="form-control"
        placeholder="Messages"
        required
        ></textarea>

        <button
        type="submit"
        className="button"
        >
        Send inquiry
        </button>
        {form.state === 'loading' ? (
        <div>Sending....</div>
        ) : form.state === 'error' ? (
        <div>{form.message}</div>
        ) : (
        form.state === 'success' && <div>Sent successfully</div>
        )}
    </form>
  );
}

x0fgdtte

x0fgdtte1#

我发现了一些可能是你问题的根源。
“useState”钩子中的“setForm”的第一个问题是,您使用空字符串('')初始化了“form”作为初始状态。但是,在代码的后面,您试图使用setForm更新form,该对象包含状态和消息属性。这可能会导致类型错误,因为form应该是字符串,但您却试图将其设置为对象。
您可以通过使用包含“state”和“message”属性的对象初始化“Form”来修复此问题:

const [form, setForm] = useState({ state: '', message: '' });

我发现的第二个问题是“handleChange”:在'handleChange'函数中,您使用prev作为回调函数的参数,这意味着prev的类型为

React.SetStateAction<{ fname: string; lname: string; email: string; message: string; }>.

但是,您在访问e.target.id和e.target.value时没有指定它们的类型,这可能会导致类型错误。
你可以通过在回调函数中为事件对象'e'和'prev'参数提供类型声明来解决这个问题,如下所示:

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { id, value } = e.target;
    setInputs((prev: React.SetStateAction<typeof inputs>) => ({
        ...prev,
        [id]: value,
    }));
};

这应该可以修复它。确保您API端点/api/contact在服务器上正确配置,以处理post req并返回预期的响应。

if (inputs.fname && inputs.email && inputs.message) {
    setForm({ state: 'loading' });
    try {
        const res = await fetch(`api/contact`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(inputs),
        });
        // Rest of the code for handling response and setting state
    } catch (error) {
        setForm({
            state: 'error',
            message: 'Something went wrong',
        });
    }
}

相关问题