Реагировать - добавить класс в пустые поля ввода - PullRequest
2 голосов
/ 18 июня 2019

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

Состояние:

this.state = {
  inputBorderError: false,
};

HTML / JSX:

<label>Name</label>
<input className={
  this.state.inputBorderError ? 'form-input form-input-fail' : 'form-input'
} />

<label>Email</label>
<input className={
  this.state.inputBorderError ? 'form-input form-input-fail' : 'form-input'
} />

<label>Message</label>
<textarea className={
  this.state.inputBorderError ? 'form-input form-input-fail' : 'form-input'
} />

CSS:

.form-input-fail {
  border: 1px solid red;
}

JS:

   let inputFields = document.getElementsByClassName('form-input');

   for (var i = 0; i < inputFields.length; i++) {
      if (inputFields[i].value === '') {
        this.setState({
          inputBorderError: true,
        });
      }
    }

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

Ответы [ 3 ]

4 голосов
/ 19 июня 2019

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

Рекомендуется присваивать каждому тегу input имя свойства. Упрощение динамического обновления их соответствующего значения состояния.

Попробуйте что-то вроде следующего, начните вводить каждый текст, затем удалите текст: https://codesandbox.io/s/nervous-feynman-vfmh5

class App extends React.Component {
  state = {
    inputs: {
      name: "",
      email: "",
      message: ""
    },
    errors: {
      name: false,
      email: false,
      message: false
    }
  };

  handleOnChange = event => {
    this.setState({
      inputs: {
        ...this.state.inputs,
        [event.target.name]: event.target.value
      },
      errors: {
        ...this.state.errors,
        [event.target.name]: false
      }
    });
  };

  handleOnBlur = event => {
    const { inputs } = this.state;
    if (inputs[event.target.name].length === 0) {
      this.setState({
        errors: {
          ...this.state.errors,
          [event.target.name]: true
        }
      });
    }
  };

  handleOnSubmit = event => {
    event.preventDefault();
    const { inputs, errors } = this.state;
    //create new errors object
    let newErrorsObj = Object.entries(inputs)
      .filter(([key, value]) => {
        return value.length === 0;
      })
      .reduce((obj, [key, value]) => {
        if (value.length === 0) {
          obj[key] = true;
        } else {
          obj[key] = false;
        }
        return obj;
      }, {});

    if (Object.keys(newErrorsObj).length > 0) {
      this.setState({
        errors: newErrorsObj
      });
    }
  };

  render() {
    const { inputs, errors } = this.state;
    return (
      <div>
        <form onSubmit={this.handleOnSubmit}>
          <label>Name</label>
          <input
            className={
              errors.name ? "form-input form-input-fail" : "form-input"
            }
            name="name"
            value={inputs.name}
            onChange={this.handleOnChange}
            onBlur={this.handleOnBlur}
          />

          <label>Email</label>
          <input
            className={
              errors.email ? "form-input form-input-fail" : "form-input"
            }
            name="email"
            value={inputs.email}
            onChange={this.handleOnChange}
            onBlur={this.handleOnBlur}
          />

          <label>Message</label>
          <textarea
            className={
              errors.message ? "form-input form-input-fail" : "form-input"
            }
            name="message"
            value={inputs.message}
            onChange={this.handleOnChange}
            onBlur={this.handleOnBlur}
          />
          <button type="submit">Submit</button>
        </form>
      </div>
    );
  }
}
0 голосов
/ 19 июня 2019

Вы должны отслеживать входное значение в состоянии, а не проверять только состояние borderStyling.

Основываясь на своем коде, вы можете изменить его на что-то вроде этого:

// keep track of your input changes
this.state = {
  inputs: {
    email: '',
    name: '',
    comment: '',
  },
  errors: {
    email: false,
    name: false,
    comment: false,
  }
};

// event handler for input changes

handleChange = ({ target: { name, value } }) => {
    const inputChanges = {
       ...state.inputs,
       [name]: value
    }

    const inputErrors = {
       ...state.errors,
       [name]: value == ""
    }

    setState({
      inputs: inputChanges,
      errors: inputErrors,
    });
}

HTML / JSX

// the name attribut for your input

<label>Name</label>
<input name="name" onChange={handleChange} className={
  this.errors.name == "" ? 'form-input form-input-fail' : 'form-input'
} />

<label>Email</label>
<input name="email" onChange={handleChange} className={
  this.errors.email == "" ? 'form-input form-input-fail' : 'form-input'
} />

<label>Message</label>
<textarea name="comment" onChange={handleChange} className={
  this.errors.comment == "" ? 'form-input form-input-fail' : 'form-input'
} />

И если вы, вероятно, хотите реализовать его с помощью CSS и js, вы можете попробовать эту статью match-an-empty-input-box-using-css-and-js

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

[Пересмотренный]

0 голосов
/ 19 июня 2019

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

Что вам нужно сделать, это сохранить отдельную ошибку для каждого входа. один из способов сделать это с помощью набора или массива в состоянии, подобном state = {errors: []}, и затем проверить

<label>Name</label>
<input className={
  this.state.errors.includes('name') ? 'form-input form-input-fail' : 'form-input'
} />

<label>Email</label>
<input className={
  this.state.errors.includes('email') ? 'form-input form-input-fail' : 'form-input'
} />
} />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...