Я пытаюсь создать приложение React с помощью Hooks, экспресс-сервера node.js и базы данных postgreSQL. Первым шагом является регистрация пользователя, но я испытываю некоторые странности с axios (а также ошибку прокси, которая может быть связана или не связана?)
Желаемое поведение: пользователь заполняет все поля и нажимает «Отправить», данные отправляются в серверную часть, сохраняются в базе данных и присваиваются идентификатору пользователя, ответ возвращается во внешний интерфейс, и все поля очищаются.
Если пользователь отправляет неполную информацию, она не сохраняется, и ответ от серверной части вызывает сообщение об ошибке для пользователя.
Ситуация 1: Пользователь заполняет все поля.
Результат 1: поведение соответствует ожидаемому, ЗА ИСКЛЮЧЕНИЕМ
(a) пользовательские данные также отображаются в строке поиска, включая пароль в виде обычного текста, и сохраняются после сохранения данных, например
http://localhost:3000/?first=Lucy&last=Who&email=who%40example.com&password=something#/
б) следующая ошибка:
Ошибка прокси: не удалось запросить / зарегистрироваться через прокси с локального хоста: 3000 на http://localhost: 5000/. См. https://nodejs.org/api/errors.html#errors_common_system_errors для получения дополнительной информации (ECONNRESET).
[примечание: я использую приложение create-реагировать, 3000 — это порт, используемый сервером разработки, я использую 5000 для своего сервера]
Ситуация 2: Пользователь вводит неполную информацию и нажимает «Отправить». Результат 2: данные отображаются в строке поиска, как указано выше, и отправляются в серверную часть, поля ввода очищаются, но, по-видимому, ответа не возвращается, и сообщение об ошибке не запускается.
Ситуация 2.1: пользователь снова отправляет ту же неполную информацию
Результат 2.1: выдается сообщение об ошибке.
Ситуация 2.2: пользователь отправляет разную неполную информацию
Результат 2.2: сообщение об ошибке исчезает.
Код (извините, если этого слишком много/недостаточно, не зная, в чем заключается проблема, немного сложно понять, что кому-то еще может понадобиться знать)
регистрация.js
import React, { useState } from "react";
import axios from "./axios";
import { Link } from "react-router-dom";
export default function Register() {
const [error, setError] = useState(false);
const [first, setFirst] = useState("");
const [last, setLast] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const formDeets = {
first: first,
last: last,
email: email,
password: password,
};
function submitReg() {
console.info("formDeets", formDeets);
axios
.post("/register", formDeets)
.then((response) => {
console.info("response.data: ", response.data);
clearAll();
if (response.data.success) {
console.info("success");
} else {
setError("true");
}
})
.catch((err) => {
console.info("register.js error in post register", err);
});
}
function clearAll() {
console.info("clear all called");
setFirst("");
setLast("");
setPassword("");
setEmail("");
}
return (
<section className = "register container">
<div className = "register-component">
{error && (
<div className = "error">
Registration failed. Please complete all fields and try
again.
</div>
)}
<form>
<label htmlFor = "first">first name</label>
<input
onChange = {(event) => setFirst(event.target.value)}
type = "text"
name = "first"
placeholder = "first name..."
value = {first}
/>
<label htmlFor = "first">last name</label>
<input
onChange = {(event) => setLast(event.target.value)}
type = "text"
name = "last"
placeholder = "last name..."
value = {last}
/>
<label htmlFor = "email">email address</label>
<input
onChange = {(event) => setEmail(event.target.value)}
name = "email"
type = "email"
placeholder = "email address..."
value = {email}
/>
<label htmlFor = "password">choose a password</label>
<input
onChange = {(event) => setPassword(event.target.value)}
name = "password"
type = "password"
placeholder = "choose a password..."
value = {password}
/>
submit
<input
type = "submit"
value = "click to accept cookies and register"
onClick = {() => submitReg()}
/>
</form>
</div>
</section>
);}
server.js (я думаю, только соответствующая часть)
app.post("/register", (req, res) => {
console.info("/register route hit");
console.info("req body", req.body);
const first_name = req.body.first;
const last_name = req.body.last;
const email = req.body.email;
const password = req.body.password;
let user_id;
if (!first_name || !last_name || !email || !password) {
res.json({
success: false,
});
return;
}
hash(password).then((hashpass) => {
db.addUser(first_name, last_name, email, hashpass)
.then((results) => {
console.info("results", results.rows[0]);
user_id = results.rows[0].id;
req.session.userId = user_id;
res.json({ success: true });
})
.catch((err) => {
console.info("err in addUser: ", err);
res.json({ success: false });
});
return;
});
}); //end of register route
server.listen(port, () => console.info(`listening on port ${port}`));
и, наконец, я вызываю axios из axios.js:
import axios from "axios";
var instance = axios.create({
xsrfCookieName: "mytoken",
xsrfHeaderName: "csrf-token"
});
export default instance;
Браузеры имеют поведение по умолчанию при отправке формы.
Это заставляет браузер переходить на новый URL-адрес после запуска вашего JS.
Вам нужно предотвратить поведение по умолчанию этого события отправки.
onClick = {() => submitReg()}
Кажется, нет никаких причин использовать здесь функцию стрелки. submitReg
не использует this
, поэтому связывание this
с функцией стрелки бессмысленно.
onClick = {submitReg}
Теперь вашей функции будет передан объект события. Используйте его, чтобы остановить поведение отправки формы по умолчанию.
function submitReg(evt) {
evt.preventDefault();
console.info("formDeets", formDeets);
Спасибо! Я боролся с этим несколько дней, и вы исправили это за 5 минут! Привязка возникла из-за того, что я конвертирую это из старого приложения, написанного с помощью классов, и по какой-то причине я не смог найти новый синтаксис для предотвращения значения по умолчанию, поскольку «событие» теперь устарело, и код vs выиграл. не принимаю это, поэтому этот ответ решил для меня две проблемы.