我无法理解状态错误,如何在 Typescript 中使用它

问题描述 投票:0回答:1

我想通过 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>
  );
}

javascript reactjs typescript next.js nodemailer
1个回答
0
投票

我发现了一些可能是您问题的根源。

'useState' 钩子中'setForm' 的第一个问题,您已经使用空字符串 ('') 作为初始状态初始化了 'form'。但是,在代码的后面,您尝试使用包含状态和消息属性的对象使用 setForm 来更新表单。这可能会导致类型错误,因为 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
在您的服务器上正确配置以处理发布请求并返回预期的响应。

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',
        });
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.