Как добавить проверку ввода в React?

1

У меня простая форма, в которойfirstName а такжеlastName .

    <label htmlFor="firstName">First Name: </label>
    <input
      type="text"
      className="form-control"
      id="firstName"
      name="firstName"
      value={basicDetails.firstName}
      onChange={(event) => handleInputChange(event)}
    />

    <label htmlFor="lastName">Last Name: </label>
    <input
      type="text"
      className="form-control"
      id="lastName"
      name="lastName"
      value={basicDetails.lastName}
      onChange={(event) => handleInputChange(event)}
    />

Для этого я пытаюсь добавить валидацию.

Правила проверки:

  • Оба поля должны принимать только текст
  • Имя является обязательным и должно состоять не менее чем из 4 символов.
  • Если поле Фамилия имеет значение, оно должно содержать не менее 3 символов.

Вещи, которые я пытался достичь,

компоненты / utils.js

export function isLettersOnly(string) {
  return /^[a-zA-Z]+$/.test(string);
}

компоненты / basic_details.js

  const handleInputChange = (event) => {
    const { name, value } = event.target;

    if (!isLettersOnly(value)) {
      return;
    }

    setValue((prev) => {
      const basicDetails = { ...prev.basicDetails, [name]: value };
      return { ...prev, basicDetails };
    });
  };

В поле ввода дескриптора я провожу проверку, чтобы проверить, имеет ли ввод значение, но я не могу понять, как отловить фактическую ошибку проверки и отобразить под соответствующим полем ввода.

Пожалуйста, помогите мне отобразить сообщение проверки в соответствующих полях.

Рабочий пример:

Изображение 5048

  • 1
    Все ваши правила проверки могут быть выполнены только с помощью HTML. Проверьте required атрибуты, minlength и pattern .
  • 0
    @Evert, на данный момент, чтобы прояснить, я сделал эти правила проверки, но в реальном времени у меня будет больше проверки .. Я настаиваю на том, чтобы выполнять проверку только в части javascript реакции, потому что нужно изменить ..
  • 0
    Когда вы хотите, чтобы проводилась проверка поля? При каждом изменении? По факту поля на Blur? Должны ли промежуточные проверки препятствовать обновлению вашего контекста / состояния?
  • 0
    Надеюсь, люди по имени Tom или Amy не хотят использовать вашу систему ...
  • 0
    @DrewReese, Да, проверка должна происходить при изменении ввода, т.е. (ввод грязный) .. И да, промежуточная проверка может предотвратить обновление контекста / состояния .. Также мы должны переместить <input> как отдельный компонент, братан, потому что я чувствую Я здесь повторяю ..
  • 0
    @JamesZ, Спасибо за ваш комментарий .. Я нахожусь в стадии изучения, так что комментарии, подобные вашим, помогут мне узнать ..
  • 0
    Начальное состояние не соответствует требованиям к длине и не позволяет обновлять контекст / состояние, так как входы находятся под контролем. У меня есть несколько работающее решение, проверка и отображение ошибок работают в компоненте, но поскольку следующая кнопка находится в Form нее нет доступа к ошибкам, чтобы предотвратить продвижение шагового двигателя. Решение здесь - поднять состояние; логически имеет смысл хранить проверки полей прямо с данными, то есть прямо в basicDetails в вашем контексте. Насколько вы готовы немного обновить форму состояния контекста?
  • 0
    @DrewReese, Да, мы можем обновить здесь контекст и сохранить валидацию в контексте .. Я могу изменить существующий код, братан. Требование состоит в том, что мне нужно сделать правильную валидацию и обновить ошибку валидации в каждом поле ввода. . Также, если нам нужно переместить следующую кнопку надлежащим образом, вы можете смело перемещать основные проблемы ..
  • 0
    @DrewReese, вы можете изменить данный код и ящик со стандартом, который вы чувствуете, и мое требование состоит в том, что мне нужна 5-ступенчатая форма, и каждый шаг будет иметь несколько входных данных, и необходимо выполнить проверку надлежащим образом и можно перейти к следующему шагу (если только входы не содержат ошибок) .. И отправка формы произойдет на последнем шаге ..
  • 0
    @DrewReese, Бро, не могли бы вы помочь мне в этом запросе относительно api stackoverflow.com/q/67223038/13270726 .. Мне просто нужно знать, как лучше реализовать выборку данных ..
Теги:
validation forms
CodeFix

2 ответа

1
Лучший ответ

Предлагаю добавитьerrors свойство к данным формы вform_context :

const [formValue, setFormValue] = useState({
  basicDetails: {
    firstName: '',
    lastName: '',
    profileSummary: '',
    errors: {},
  },
  ...
});

Добавить валидацию вbasic_details подчиненная форма:

const ErrorText = ({ children }) => (
  <div style={{ color: 'red' }}>{children}</div>
);

const BasicDetails = () => {
  const [value, setValue] = React.useContext(FormContext);
  const { basicDetails } = value;

  const handleInputChange = (event) => {
    const { name, value } = event.target;

    if (!isLettersOnly(value)) {
      setValue((value) => ({
        ...value,
        basicDetails: {
          ...value.basicDetails,
          errors: {
            ...value.basicDetails.errors,
            [name]: 'Can have only letters.',
          },
        },
      }));
      return;
    }

    switch (name) {
      case 'firstName': {
        const error = value.length < 4 ? 'Length must be at least 4.' : null;
        setValue((value) => ({
          ...value,
          basicDetails: {
            ...value.basicDetails,
            errors: {
              ...value.basicDetails.errors,
              [name]: error,
            },
          },
        }));
        break;
      }

      case 'lastName': {
        const error = value.length < 3 ? 'Length must be at least 3.' : null;
        setValue((value) => ({
          ...value,
          basicDetails: {
            ...value.basicDetails,
            errors: {
              ...value.basicDetails.errors,
              [name]: error,
            },
          },
        }));
        break;
      }

      default:
      // ignore
    }

    setValue((prev) => {
      const basicDetails = { ...prev.basicDetails, [name]: value };
      return { ...prev, basicDetails };
    });
  };

  return (
    <>
      <br />
      <br />
      <div className="form-group col-sm-6">
        <label htmlFor="firstName">First Name: </label>
        <input
          type="text"
          className="form-control"
          id="firstName"
          name="firstName"
          value={basicDetails.firstName}
          onChange={(event) => handleInputChange(event)}
        />
      </div>
      <br />
      {basicDetails.errors.firstName && (
        <ErrorText>{basicDetails.errors.firstName}</ErrorText>
      )}
      <br />
      <br />
      <div className="form-group col-sm-4">
        <label htmlFor="lastName">Last Name: </label>
        <input
          type="text"
          className="form-control"
          id="lastName"
          name="lastName"
          value={basicDetails.lastName}
          onChange={(event) => handleInputChange(event)}
        />
      </div>
      <br />
      {basicDetails.errors.lastName && (
        <ErrorText>{basicDetails.errors.lastName}</ErrorText>
      )}
      <br />
    </>
  );
};

Наконец, проверьте значения полей и ошибки, чтобы установитьdisabled атрибут на следующей кнопке вindex.js . Первый!(value.basicDetails.firstName && value.basicDetails.lastName) condition обрабатывает состояние начальных / пустых значений, а второе условие обрабатывает значения ошибок.

{currentPage === 1 && (
  <>
    <BasicDetails />
    <button
      disabled={
        !(
          value.basicDetails.firstName && value.basicDetails.lastName
        ) ||
        Object.values(value.basicDetails.errors).filter(Boolean).length
      }
      onClick={next}
    >
      Next
    </button>
  </>
)}

Этот шаблон можно повторить для следующих шагов.

Изображение 5048

Поделиться
Источник
  • 0
    Спасибо за ваше быстрое решение, и усилия, которые вы прилагаете, очень заметны, брат ... И вы четко предоставили решение, в котором я нуждаюсь ... Мне также нужно добавить проверку размытия, братан ... Мне очень жаль, что я не упомянул об этом ... Мне нужно было реализовать как грязную, так и проверку размытия ...
  • 0
    Также, если у вас есть время, не могли бы вы помочь мне сделать входные данные отдельным компонентом? (Просто прошу, братан) ..
  • 0
    @Undefined Поскольку вы проверяете входные данные при каждом изменении, я не уверен, что onBlur будет вам полезна, входные данные будут уже проверены с момента последнего события изменения, прежде чем поле можно будет расфокусировать. Я также рекомендую не изобретать колесо заново, если вы можете, многие библиотеки проверки полей форм существуют специально для тех функций, о которых вы спрашиваете. Какого рода факторизацию входных данных вы ищете? Простое разбиение на компоненты, чтобы сделать код более СУХИМ?
  • 0
    Спасибо, братан. Мой руководитель попросил меня не включать стороннюю библиотеку и попросил меня добиться этого чисто реактивным способом, и именно поэтому я ищу помощь .. Также он сказал, что он не должен видеть никаких повторений кода для входные данные, поэтому он хочет, чтобы я сделал это как отдельный компонент и должен передать необходимые реквизиты этому компоненту.
  • 0
    Не знаю, сбиваю ли я вас с толку .. Но на данный момент ваша помощь гораздо более ощутима, братан ..
  • 0
    @ Неопределенные коды проверкиandbox.io/ s/…
  • 0
    Спасибо за ваши постоянные усилия, чтобы помочь мне в решении проблемы, братан .. Очень признателен и еще раз спасибо .. Это мне очень помогает ..
0

Сначала вы должны получить преобразование контролируемого компонента в неконтролируемую ошибку компонента в вашей консоли. Для управляемого компонента всегда предпочтительно использовать состояние для установки значения для входа. А с помощью обработчика onChange вы устанавливаете состояние. Я постараюсь объединить в один компонент, чтобы вы поняли идею и применили свой случай.

import React, {useState}  from 'react';
import {isLettersOnly} from './components/utils'; // not sure where it is in your folder structure

const MyInputComponent = ({value, ...props}) => {
   const [inputValue, setInputValue] = useState(value || ''); // input value should be empty string or undefined. null will not be accepted.
   const [error, setError] = useState(null);


   const handleChange = event => {
      
    const { name, value } = event.target;

     if (!isLettersOnly(value)) {
         setError('Invalid Input');
     }
      setInputValue(value);
     
   }

   return (
    <>
     <input
      value={inputValue}
      onChange={handleChange}
      {...props}
    />
    {error && (
        <span className={"error"}>{error}</span>
    )}
    </>
   )
}

export default MyInputComponent;

Это очень элементарный компонент. просто чтобы показать концепцию. Затем вы можете импортировать этот компонент в качестве поля ввода и передать необходимые реквизиты, такие как name, className и т. Д. От родителя.

import React from 'react';
import MyInputComponent from 'components/MyInputComponent';

const MyForm = (props) => {
  return props.data && props.data.map(data=> (
    <MyInputComponent
      name="lastName"
      className="form-control"
      value={data.lastName}
  ));
}
Поделиться
Источник
  • 0
    Нет, я не могу установить такое значение в useState. Я получаю значения из context api .. Что произойдет, если форма имеет несколько входов, скажем, 50 входов в этом компоненте .. Нужно ли нам включать 50 useState ?
  • 0
    Основываясь на вашем комментарии в решении, not sure where it is in your folder structure утилиты находятся в разделе components/utils.js ..
  • 0
    Я обновил комментарий. Суть React - создание повторно используемых компонентов по принципу DRY. Вы создадите свой собственный компонент ввода, в который уже интегрирована валидация вместе с другими динамическими реквизитами, а затем используйте его в качестве компонента ввода.
  • 0
    хорошо, внесены еще несколько изменений, чтобы показать, как вы можете использовать его с массивом данных. вы можете передавать данные и умножать этот компонент сколько угодно раз с разными реквизитами. любая опора, кроме value будет передана на input и по умолчанию они будут контролироваться и проверяться, а также будет заполнять текст ошибки внизу, когда проверка не удалась.
  • 0
    извините, возник конфликт с значениями props.value и setState. вместо этого заменил его на inputValue.

Другие вопросы

  • как выполнить итерацию во вложенном массиве1 ответ

    Здравствуйте, у меня такой структурированный JSON, и мне нужно перебрать элементы[ { "name": "About You", "questions": [ { "questionText": "What is your surname?", "answers": [ { "t...

  • Состояние редактирования внутри модального окна1 ответ

    Я делаю небольшое приложение для заметок. Когда пользователь пишет свой заголовок и заметку и нажимает «Отправить», заметка помещается на страницу ... Я хочу иметь возможность редактировать заметку. При нажатии кнопки редактирования появляется модальное окно, и я хочу, чтобы заголовок и примечание п...

  • Выберите элемент, необходимый в vuejs, не работает1 ответ

    Я новичок в vuejs. Я хочу сделать элемент выбора из раскрывающегося списка обязательным, я попытался добавить требуемый атрибут, как в приведенном ниже коде. <v-select :items="fournisseursByClient" ...

  • как добавить ссылки на липкую панель навигации1 ответ

    Я попытался добавить фоновое изображение для своего веб-сайта django, и это вообще не сработало. Я использую этот ответ из stackoverflow, а также ссылку на вопрос stackoverflow. Но это не сработало. А также я переношу изменения в базу данных. добавить фоновое изображение как в методе cssbackground-i...

  • Включение и отключение кнопки отправки с флажками1 ответ

    Я использую Formik для своих форм React, которые я тоже довольно новичок, у меня есть форма с двумя флажками и кнопкой отправки, которая по умолчанию отключена. Мне нужно найти способ проверить, установлен ли флажок. Если все два флажка были отмечены, кнопка отправки активна, а если какой-либо из ни...

  • Состояние реакции не меняется после нажатия какой-либо кнопки2 ответ

    После вызоваhandleButton нажав наLog In кнопку один раз, значениеlogInStatus пустой. Однако после второго щелчка значениеlogInStatus изменится. Я знаю, что setState - это асинхронный вызов, поэтому он не будет обновлять значениеlogInStatus немедленно. Как мне подойти к решению?import React, {setStat...

  • Как заблокировать меню боковой панели, скрытое при обновлении страницы1 ответ

    У меня есть меню боковой панели, которое было успешно скрыто и отображено. Когда меню боковой панели скрыто и я обновляю страницу или браузер, скрытое меню боковой панели вернется к своему первоначальному виду, а не в том положении, в котором оно было скрыто. Вопрос в том, как заблокировать, чтобы о...

  • Калькулятор JS форм1 ответ

    Я сделал этот простой калькулятор своим первым проектом на JS. Я был на одном курсе, где мне сказали, что программисты «ленивы», поэтому они стараются писать как можно меньше кода. И вот мой вопрос. Я думаю, что мой калькулятор действительно долго работает над кодом. Я хотел бы знать, есть ли способ...

  • Как создать html-страницу со ссылкой [закрыто]1 ответ

    Закрыто . Этот вопрос должен быть более конкретным . В настоящее время он не принимает ответы. Хотите улучшить этот вопрос? Обновите вопрос, чтобы он фокусировался только на одной проблеме, отредактировав этот пост . Закрыт в прошлом месяце . Уточните этот вопрос Как разместить видео ключи на моем...

  • Компонент экспорта React, который не отображается в PNG1 ответ

    Я пытаюсь экспортировать диаграмму в изображение, и я хочу, чтобы изображение диаграммы имело настраиваемую легенду, которая не отображается на экране. Как я могу это сделать? На данный момент я попытался экспортировать с помощью response-component-export-image, но если компонент не отображается, сс...

CodeFix
Цитата дня

"Завидую тестировщикам: все хотят с ними дружить."

Эндрю Таненбаум