Как показать ошибку на конкретном входе в реакции?

У меня есть этот state, который представляет продукты.

const [rowsData, setRowsData] = useState([
    { width: "", height: "", quantity: "" },
  ]);

И это table, который пользователь может добавить, сколько строк (товаров) по мере необходимости или удалить.

return (
    <> 
      {rowsData.map((data, index) => {
        const { width, height, quantity} = data;
        return (
          <tr key = {index}>
            <td>{index + 1}</td>
            <td>
              <input
                type = "number"
                value = {width}
                onChange = {(evnt) => handleChangeEvent(index, evnt)}
                name = "width"
                className = {wError ? "input input-error border-2 input-bordered w-full max-w-xs" : "input input-bordered w-full max-w-xs"}            
              />
            </td>
            <td>
              <input
                type = "number"
                value = {height}
                onChange = {(evnt) => handleChangeEvent(index, evnt)}
                name = "height"
                className = {hError ? "input input-error border-2 input-bordered w-full max-w-xs" : "input input-bordered w-full max-w-xs"}
              />{" "}
            </td>
            <td>
              <input
                type = "number"
                value = {quantity}
                onChange = {(evnt) => handleChangeEvent(index, evnt)}
                name = "quantity"
                className = {qError ? "input input-error border-2 input-bordered w-full max-w-xs" : "input input-bordered w-full max-w-xs"}
              />{" "}
            </td>
            <td>
              {index !==0 ? <button className = "btn" onClick = {() => deleteTableRows(index)}>
                x
              </button>: null}
            </td>
          </tr>
        );
      })}

Функция handlChange() обнаруживает любые изменения в полях input и запускает setState.

const handleChangeEvent = (index, evnt) => {
    const { name, value } = evnt.target;
    const rowsInput = [...rowsData];
    rowsInput[index][name] = value;
    setRowsData(rowsInput);
  };

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

Мое решение проблемы было таким:

1- A сделал 3 ошибки usestats для каждого поля (w->ширина, h->высота, q->количество)

  const [wError, setWError] = useState(false);
  const [hError, setHError] = useState(false);
  const [qError, setQError] = useState(false);

2- Я проверил value каждого поля ввода, является ли это числом или нет.

const createOrder = () => {
    let wCheck, hCheck, qCheck

    rowsData.map((e) => {
       wCheck = !isNaN(e.width) && !isNaN(parseFloat(e.width));
       hCheck = !isNaN(e.height) && !isNaN(parseFloat(e.height));
       qCheck = !isNaN(e.quantity) && !isNaN(parseFloat(e.quantity));

    });
  };

3- Установите переменные ошибок (wError, hError, qError), чтобы они были противоположны проверочным переменным (wCheck, hCheck, qCheck).

      setWError(!wCheck);
      setHError(!hCheck);
      setQError(!qCheck);

4- Я стилизую поле ввода на основе переменной ошибки (как показано в первом фрагменте).

className = {qError ? "input input-error border-2 input-bordered w-full max-w-xs" : "input input-bordered w-full max-w-xs"}

Решение Заключение

Это решение ужасно. В нем есть несколько ошибок, которые я не смог исправить

Как видите, ошибка основана только на последнем поле ввода. Таким образом, средство проверки ошибок помечает весь столбец как ошибку (3-й столбец), а иногда помечает весь столбец как действительный (1-й столбец).

Как изменить функцию, чтобы она нацеливалась на определенное поле ввода?

Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
CSS: FlexBox
CSS: FlexBox
Ранее разработчики использовали макеты с помощью Position и Float. После появления flexbox сценарий полностью изменился.
0
0
142
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете добавить новое свойство в свой массив продуктов, в котором будет храниться сообщение об ошибке, или даже логическое значение, которое будет true, когда ввод имеет некоторую ошибку проверки. В вашей функции handleChangeEvent() вы можете проверить, является ли значение недопустимым, и установить это поле. В цикле вы проверяете поле и, если есть ошибка, устанавливаете красную границу для ввода текущей итерации.

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

Пример ниже:

export function App(props) {

  const [rows, setRows] = useState([
    {value: '', error: false},
    {value: '', error: false},
    {value: '', error: false},
  ])

  function handleChangeEvent(evt, index) {
    let value = evt.target.value
    rows[index].value = value
    rows[index].error = !isNaN(value) && !isNaN(parseFloat(value))
    setRows([...rows])
  }

  return (
    <div className='App'>
      <table>
        <tbody>
          {rows.map((row, index) => (
            <tr key = {index}>
              <input 
                style = {{'border': row.error ? '1px solid red' : ''}} 
                value = {row.value} 
                onChange = {(evt) => handleChangeEvent(evt, index)} 
                placeholder = "Enter value"
               />
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

Чтобы проверить, есть ли у какого-либо ввода ошибка для отключения операции отправки, вы можете проверить, является ли какое-либо поле errortrue. Если нет ни одной с true, форма действительна.

Пример игровой площадки React

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