#javascript #reactjs #react-hooks
Вопрос:
Я пытаюсь создать пользовательский крюк, который можно будет использовать в любой форме, но у меня есть проблема, в которой я не уверен, в чем она заключается. всякий раз, когда я начинаю вводить текст в поля, он теряет фокус, чтобы ввести его снова, вам нужно будет щелкнуть по нему, и так далее. это нехорошо, и я был бы признателен, если бы кто-нибудь мог помочь мне решить эту ошибку.
useForm.js
import { useState } from "react";
const useForm = () => {
const [values, setValues] = useState({
// contact form
});
const [errors, seterrors] = useState({});
const handleChange = (e) => {
const { name, value } = e.target;
setValues({
...values,
[name]: value
});
// console.log(name, value);
};
const validate = (data) => {};
const handleSubmit = (e) => {
e.preventDefault();
// console.log(e);
};
// console.log(values);
return {
handleChange,
values,
handleSubmit
};
};
export default useForm;
Form.js
import InputGroup from "./InputGroup";
import useForm from "./useForm";
const Form = () => {
const fields = [
{
label: "First Name",
className: "input-group",
name: "firstName",
placeholder: "John",
type: "text"
},
{
label: "Last Name",
className: "input-group",
name: "lastName",
placeholder: "Doe",
type: "text"
},
{
label: "Email",
className: "input-group",
name: "email",
placeholder: "JohnDoe@example.com",
type: "email"
},
{
label: "Phone Number",
className: "input-group",
name: "Phone",
placeholder: " 234 (0)81 234 5678",
type: "text"
// pattern: "/^[ ]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-s./0-9]*$/g"
},
{
label: "Comments",
className: "input-group",
name: "comment",
placeholder: "Message",
type: "textarea"
}
];
const { values, handleChange, handleSubmit } = useForm();
//funtion to generate id based on fields lenght
const id = () => {
const head = Date.now.toString(36);
const tail = Math.random().toString(36).substr(2);
return head tail;
};
console.log(id);
return (
<form onSubmit={handleSubmit}>
{fields.map((field) => (
<InputGroup
key={id}
value={values}
onChange={handleChange}
{...field}
/>
))}
<button>submit</button>
</form>
);
};
export default Form;
Ввод
const Input = ({ ...props }) => {
return <input {...props} />;
};
export default Input;
Комментарии:
1. где это
InputGroup
?2. Проблема в том , что вы используете
key
, и в этом есть не одна проблема. В настоящее время все элементы имеют один и тот же ключ: экземпляр функции, который вы назвалиid
. И этот экземпляр создается заново при каждом рендеринге. Когда вы вводите одну букву, компонент снова отображается, и ваша функция идентификатора будет другим экземпляром. Вы можете просто использоватьname
каждое поле в качестве ключа.
Ответ №1:
Вы неправильно используете свою id
функцию, вы только ссылаетесь на нее, а не вызываете ее, измените —
<InputGroup
key={id}
Для
<InputGroup
key={id()}
или еще лучше, лучшее название, использование глагола облегчило бы решение проблемы, так как теперь она выглядит как функция, а не переменная
<InputGroup
key={buildId()}
или что угодно, но еще лучше, вы должны использовать статическое уникальное значение для ключа (т. Е. уникальное, но не изменяющееся между визуализациями, поэтому использование меток времени-плохая идея), чтобы вы могли добавить уникальный идентификатор к каждому field
и использовать его —
const fields = [
{
id: <some unique ID>, <!---- here
label: "First Name",
className: "input-group",
name: "firstName",
placeholder: "John",
type: "text"
}
...
]
...
<InputGroup
key={field.id}