Привязка события OnClick в файле React.js

Я хотел бы передать идентификатор родительского элемента div по щелчку этого элемента div или любого дочернего элемента того же элемента div. Но я не могу этого добиться. Пожалуйста, скажите мне, где я делаю ошибку. Код ниже:

viewMore: function(i,j){
        console.log('You clicked: ', i  );
    },

render : function(){
  var attributeId = "groups_";
  attributeId+= index;
  return(
  //parent div
    <div className="groups" id={attributeId} onClick={this.viewMore}>
        <div className="floatLeft"> Group Name: <h3>My Name</h3></div>
            <span className="floatRight typeCd">POC</span>
        <div className="clearfix"> Key Attributes: 
            <ul>
                <li> POC 1</li>
            </ul>
        </div>
    </div>
    )
};

Ответ 1

viewMore = (i,j) => () => {
    console.log(i,j)
}

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

Ответ 2

Так как я вижу подобные предложения в нескольких местах, я собираюсь переместить свой комментарий в ответ, чтобы обеспечить дополнительное представление:

class TestComponent extends React.Component {
  constructor() {
    super();
    this.onClick = this.handleClick.bind(this);
  }

  handleClick(event) {
    const {id} = event.target;
    console.log(id);
  }

  render() {
    return (
      <div>
        <h3 id={this.props.id} onClick={this.onClick}>
          {this.props.name}
        </h3>
      </div>
    );
  }
}

Это позволяет:

  1. избегать ненужных привязок
  2. получить доступ к id и любым другим свойствам гораздо более в стиле React-ive.

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

ОБНОВЛЕНИЕ 1 - 28 ноября 2016

Добавлена ссылка на CodePen из комментариев выше.

ОБНОВЛЕНИЕ 2 - 30 марта 2017

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

Сказав это, это 2017. Используйте ES6, не так ли?

ОБНОВЛЕНИЕ 3 - 12 мая 2017

Если вы используете преобразование свойств класса, вы можете еще больше упростить его:

class TestComponent extends React.Component {
  onClick = (event) => {
    const {id} = event.target;
    console.log(id);
  }

  render() {
    return (
      <div>
        <h3 id={this.props.id} onClick={this.onClick}>
          {this.props.name}
        </h3>
      </div>
    );
  }
}

ОБНОВЛЕНИЕ 4 - 4 февраля 2018

Из-за улучшений bind и друзей в V8 (Chakra и тому подобное, вероятно, тоже), вам может быть лучше использовать this.click.bind(this) или обернуть его в функцию стрелки при переходе к onClick.

Зачем?

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

ПРИМЕЧАНИЕ 1. - 14 апреля 2018 г.

Помните, что метод, упомянутый в обновлении 4, по-прежнему вызывает некоторые проблемы с производительностью, поскольку при каждом проходе render новая функция создается в результате bind. Это, в свою очередь, повлияет на дочерний компонент и приведет к ненужным повторным визуализациям, поскольку функция меняется каждый раз.

То же самое происходит, когда вы передаете встроенную функцию стрелки.

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

Итак, это:

class Person {
  printA = () => { console.log('a') }
}

будет выглядеть так:

function _classCallCheck(instance, Constructor) {...abridged...}

var Person = function Person() {
  _classCallCheck(this, Person);

  this.printA = function () {
    console.log('a');
  };
};

Ответ 3

Я сделал обновленный ответ для ES6 здесь: fooobar.com/questions/27553/...

По существу, вы можете использовать выражения функции стрелки, которые имеют преимущество сохранения this:

onClick={(event)=>this.viewMore(attributeId, event)}

Как и в случае с этим редактированием, если вы используете Babel со включенной стадией 2, вы можете использовать свойство, подобное этому:

// Within your class...
viewMore = (event) => { /* ... */ }
// Within render method in your JSX
onClick = {this.viewMore}

Ответ 4

Вы можете использовать функцию карри.

ES5:

viewMore(param) { // param is the argument you passed to the function
    return function(e) { // e is the event object that returned

    };
}

ES6

viewMore = param => e => {
  // param is the argument you passed to the function
  // e is the event object that returned
};

И просто используйте это так:

onClick={this.viewMore("some param")}

Ответ 5

Вот обновление и обзор предыдущих ответов:

  • Использование onClick = {this.viewMore.bind(this, attributeId)} @HenrikAndersson . Хотя этот подход служит цели, он использует синтаксис связывания, с которым многие из них не являются удобными.
  • Используя общедоступное поле класса, указанное @ZenMaster. решение имеет более или менее ту же производительность, оно также имеет лучший синтаксис. Но это становится сложным, когда мы должны передать параметр.

    class TestComponent extends React.Component {
      onClick = (event) => {
        const {id} = event.target;
        console.log(id);
      }
    
      render() {
        return (
          <div>
            <h3 id={this.props.id} onClick={this.onClick}>
              {this.props.name}
            </h3>
          </div>
        );
      }
    }
    

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

Лучшее решение:

class MyComponent extends React.Component {

    handleClick = (item) => (e) => {
        e.preventDefault()    
        console.log(`This has access to item ${item}! and event(e)`)
    }

    render(){
        const item={ id:'1', value: 'a' }
        return(
            <button onClick={ this.handleClick(item) }  >Click</button>
        )
    }

}

Ссылка: Управлять событиями со стрелками в приложении React