#javascript #reactjs #fetch
Вопрос:
я пытаюсь создать базовую форму ввода электронной почты с помощью react и fetch.
Я получаю ряд ошибок, которые я не совсем понимаю, откуда они берутся.
я следую https://mattboldt.com/2020/05/02/formdata-with-react-hooks-and-fetch/
Просто хочу, чтобы все было очень просто. Пытаюсь просто отправить это в api аутентификации в качестве тестера,
{"email":"oahnsodi@gmail.com","name":"aoisdnasd"}
по сути, это компонент с ошибкой.
function FormAlert(props) {
const { type, message, ...otherProps } = props;
return (
<div>
{type ==="error" ? "danger":"success"}
{}
<div className="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-green-100">
<CheckIcon className="h-6 w-6 text-green-600" aria-hidden="true" />
</div>
<div className="mt-3 text-center sm:mt-5">
<Dialog.Title as="h3" className="text-lg leading-6 font-medium text-gray-900">
Email successful
</Dialog.Title>
<div className="mt-2">
<p className="text-sm text-gray-500">
Welcome to the Plantform Movement!
</p>
</div>
</div>
</div>
)
};
const AuthForm =(props)=> {
const [pending, setPending] = useState(false);
// const { handleSubmit, register, errors, getValues } = useForm();
const [user, setUser] = useState({ name: 'Sign Up!' })
console.log(user)
// Handle form submission
const submit = e => {
setPending(true);
console.log({ "name":user[name],"email":user[email] })
const payload = JSON.stringify({ "name":user[name],"email":user[email] })
console.log(payload)
e.preventDefault()
fetch('xxxxx/fakeAuth', {
method: 'POST',
mode:'no-cors',
headers: { 'Content-Type': 'application/json' },
body: payload,
})
.then(res => res.json())
.then(json => setUser(json))
.catch((error) => {
// Show error alert message
console.log(error)
})
.finally(() => {
// Hide pending indicator
setPending(false);
});
}
return (
<div className="pt-8">
<div>
<h3 className="text-lg leading-6 font-medium text-gray-900">Personal Information</h3>
<p className="mt-1 text-sm text-gray-500">Use a permanent address where you can receive mail.</p>
</div>
<div className="mt-6 grid grid-cols-1 gap-y-6 gap-x-4 sm:grid-cols-6">
<form onSubmit={submit}>
<div className="sm:col-span-3">
<label htmlFor="name" className="block text-sm font-medium text-gray-700">
Full name
</label>
<div className="mt-1 shadow-sm focus:ring-green-500 focus:border-green-500 block w-full sm:text-sm border-gray-300 rounded-md">
<input
type="text"
name="user[name]"
id="name"
value={user.name}
onChange={e => setUser({ ...user, name: e.target.value })}
autoComplete="given-name"
className="shadow-sm focus:ring-green-500 focus:border-green-500 block w-full sm:text-sm border-gray-300 rounded-md"
/>
</div>
</div>
<div className="sm:col-span-4">
<label htmlFor="email" className="block text-sm font-medium text-gray-700">
Email address
</label>
<div className="mt-1">
<input
id="email"
name="user[email]"
value={user.email}
onChange={e => setUser({ ...user, email: e.target.value })}
autoComplete="email"
className="shadow-sm focus:ring-green-500 focus:border-green-500 block w-full sm:text-sm border-gray-300 rounded-md"
/>
</div>
</div>
<div className="sm:col-span-4">
<label htmlFor="confirmEmail" className="block text-sm font-medium text-gray-700">
Confirm email
</label>
<div className="mt-1">
<input
id="confirmEmail"
name="confirmEmail"
type="confirmEmail"
autoComplete="confirmEmail"
className="shadow-sm focus:ring-green-500 focus:border-green-500 block w-full sm:text-sm border-gray-300 rounded-md"
/>
</div>
</div>
</form>
</div>
<div className="mt-5 sm:mt-6">
<button
type="submit"
className="inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 bg-green-600 text-base font-medium text-white hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 sm:text-sm"
disabled={pending}
onClick = {submit}
>
{!pending amp;amp; <span>Submit</span>}
{pending amp;amp; (
<>
<svg
className="animate-spin -ml-1 mr-3 h-5 w-5 text-white"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
></circle>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
></path>
</svg>
<span>Please wait...</span>
</>
)}
</button>
</div>
</div>
)
}
Это возвращает ошибку
Unhandled Runtime Error
TypeError: Cannot read property 'name' of undefined
Source
src/components/Authentication/AuthModal.js (84:30) @ AuthForm
82 | name="user[name]"
83 | id="name"
> 84 | value={user.name}
| ^
85 | onChange={e => setUser({ ...user, name: e.target.value })}
86 | autoComplete="given-name"
87 | className="shadow-sm focus:ring-green-500 focus:border-green-500 block w-full sm:text-sm border-gray-300 rounded-md"
Это подпитывает этот компонент высокого уровня.
/* This example requires Tailwind CSS v2.0 */
import { Fragment, useState } from 'react'
import { Dialog, Transition } from '@headlessui/react'
import { CheckIcon } from '@heroicons/react/outline'
import { useForm } from "react-hook-form";
// import { useRouter } from "next/router";
export default function AuthModal() {
const [open, setOpen] = useState(false);
// setUser(name="")
const [formAlert, setFormAlert] = useState(null);
return (
<>
<button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
onClick={() => setOpen(true)}
>
Signup
</button>
{open ? (
<Transition.Root show={open} as={Fragment}>
<Dialog as="div" static className="fixed z-10 inset-0 overflow-y-auto" open={open} onClose={setOpen}>
<div className="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Dialog.Overlay className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
</Transition.Child>
{/* This element is to trick the browser into centering the modal contents. */}
<span className="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">
amp;#8203;
</span>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
enterTo="opacity-100 translate-y-0 sm:scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<div className="inline-block align-bottom bg-white rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-sm sm:w-full sm:p-6">
{formAlert amp;amp; (
<div className="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-green-100">
<FormAlert type={formAlert.type} message={formAlert.message} />
</div>
)}
<AuthForm
/>
</div>
</Transition.Child>
</div>
</Dialog>
</Transition.Root>
) : null}
</>
)
}
Что я здесь делаю не так? Должен ли я просто использовать формы с реактивными крючками? Я просто хочу иметь возможность создать минимальную версию регистрации, отправив полезную нагрузку json с электронной почтой и именем atm и изменив состояние, чтобы у меня были конкретные результаты для этого более высокого компонента.
Сделал некоторые обновления, все еще не уверен, почему я получаю 404 ошибки при нажатии на сервер, сейчас ошибка выглядит так.
SyntaxError: Unexpected end of input
at eval (AuthModal.js?5485:123)
и ошибка 400, с этим журналом консоли в качестве примера,
{name: undefined, email: undefined}email: undefinedname: undefined__proto__: Object
AuthModal.js?5485:113 {}
AuthModal.js?5485:105 {name: "oaisdn091n2d", email: "12ed09j23podm@gmail.com"}
Спасибо!
Ответ №1:
const payload = JSON.stringify({ "name":user[name],"email":user[email] })
вам нужно передать имя и адрес электронной почты в виде строки пользователю, как эти user['name']
user['email']
, как эти.