Не удается передать заголовок метода обработке событий в разметке React - PullRequest
0 голосов
/ 23 сентября 2018

В моем render () У меня есть следующий компонент с обработкой событий.

render() { ...
  <input type="text" 
         onChange={(_) => { this.restate("email", _.target.value); }} />
}

private restate(type: string, input: any) { ...
  if (type === "email")
    this.setState({ ... });
}

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

render() { ...
  <input type="text" onChange={ this.handleEmail } />
}

private handleEmail(data: React.ChangeEvent<HTMLInputElement>) {
  console.log("hit before: " + data.target.value);
  console.log(this);
  this.restate("email", data.target.value);
}

Изменение в разметке, похоже, работает, потому что метод handleEmail (...) вызывается.Однако я получаю сообщение об ошибке, в котором говорится, что restate (...) не является методом undefined , и, фактически, когда я исследую, что такое , это ,Я обнаружил, что это undefined .

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

Ответы [ 2 ]

0 голосов
/ 25 сентября 2018

Чтобы использовать this внутри функции onClick, вам необходимо связать ее внутри конструктора.Вы также можете использовать связывание в render(), но это не рекомендуется, так как bind будет вызываться несколько раз.React Docs рекомендует использовать bind внутри конструктора, как этот

constructor() {
  super(); 
  this.handleEmail = this.handleEmail.bind(this);
}

Это не что-то особенное для React, его JavaScript.Свой дизайн.

Это то, что bind делает

Метод bind () создает новую функцию, которая при вызове имеет ключевое слово thisустановите заданное значение с заданной последовательностью аргументов, предшествующей любому указанному при вызове новой функции.

Вопрос

Почему вы работали в первом примере?

render() { ...
  <input type="text" 
         onChange={(_) => { this.restate("email", _.target.value); }} />
}

Это потому, что вы использовали функцию стрелки ES6 ()=> {}.Это также называется жирной стрелкой.

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

Ваш второй пример сработал бы, если бы вы использовали вот так

render() { ...
  <input type="text" onChange={ ()=> this.handleEmail() } />
}

Я бы посоветовал прочитать эту превосходную статью , чтобы узнать большеподробности о bind

0 голосов
/ 24 сентября 2018

Я думаю, что вы должны сделать это

render() { ...
  <input type="text" onChange={(e) => this.handleEmail(e) } />
}

Я думаю, что причина, по которой ваш метод пересчета не был методом undefined, заключается в том, что ваш метод не был привязан к компоненту.Чтобы ваши методы были частью класса реакции, вам нужно привязать этот метод к классу.Есть несколько способов сделать это.В конструкторе классов, например:

 constructor(props) {
  super(props);
  this.handleEmail = this.handleEmail.bind(this);
 }

или внутри функции рендеринга, как я показал выше.Третье - использовать функцию стрелки внутри тела класса следующим образом:

handleEmail = () => {
  // call this function from render 
  // and this.whatever in here works fine.
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...