проблема с обработчиком пользовательских форм в react

#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}