React onClick - передати подію з параметром


93

Без параметра

function clickMe(e){
  //e is the event
}

<button onClick={this.clickMe}></button>

За допомогою параметра

function clickMe(parameter){
  //how to get the "e" ?
}
<button onClick={() => this.clickMe(someparameter)}></button>

Я хочу отримати event. Як я можу це отримати?

Відповіді:


167

Спробуйте це:

<button onClick={(e) => {
     this.clickMe(e, someParameter)
}}>Click Me!</button>

І у вашій функції:

function clickMe(event, someParameter){
     //do with event
}

2
Це призвело до помилки eslint ( eslint.org/docs/rules/arrow-parens.html ). Я зробив onClick={(e) => { this.clickMe(e, someparameter) }}
обернення

1
Так @kretzm Якщо ми не даємо фігурних дужок, це діє як вираз повернення, коли це один рядок, інакше ми повинні використовувати фігурні дужки для обтікання як тіло функції.
Jyothi Babu Araja

4
Я просто хочу додати, що це не рекомендований синтаксис. З документації responsejs: Проблема цього синтаксису полягає в тому, що кожен раз, коли кнопка відображається, створюється інший зворотний виклик. У більшості випадків це нормально. Однак, якщо цей зворотний виклик передається як підказка для нижчих компонентів, ці компоненти можуть зробити додатковий рендеринг. Як правило, ми рекомендуємо прив'язувати конструктор або використовувати синтаксис полів класу, щоб уникнути такого роду проблем із продуктивністю. Більш детальна інформація на reactjs.org
northernwind

1
@Victor. Так, ти правий. Але якщо ви хочете, щоб контекст вашого батька був у вашому зворотному виклику, вам потрібно мати різний зворотний виклик для кожного візуалізації. Насправді, я думаю, це компроміс.
Jyothi Babu Araja

@JyothiBabuAraja Я вважаю, що найкращим рішенням є використання data-*атрибутів у HTML5. Будь ласка, перегляньте мою відповідь нижче, щоб дізнатися більше.
Гаррі Чанг

34

З ES6 ви можете зробити коротшим способом, як це:

const clickMe = (parameter) => (event) => {
    // Do something
}

І використовуйте його:

<button onClick={clickMe(someParameter)} />

це також вирішує створення нового питання зворотного дзвінка? stackoverflow.com/questions/42597602 / ...
Отани Shuzo

1
на додаток до цього, ви можете надіслати кілька параметрів. const clickMe = (параметр1, параметр2) => (подія) => {// Зробити щось}
AhuraMazda

1
Цей також запускається, коли компонент змонтовано, ваш код повинен бути:onClick={(e) => clickMe(someParameter)(e)}
Олександр Кім

Так само, якби просто clickMe, ви також можете знищити подію, навіть якщо ви не визначаєте її як параметр.
Minh Kha

Дякую за це. Це працює. Але чому там const clickMe = (parameter) => (event) => {...} замість цього const clickMe = (parameter) => {...}?
zrna

16

Рішення 1

function clickMe(parameter, event){
}

<button onClick={(event) => {this.clickMe(someparameter, event)}></button>

Рішення 2. Використання функції прив'язки вважається кращим, ніж спосіб функції стрілки, у рішенні 1. Зауважте, що параметр події повинен бути останнім параметром у функції обробника

function clickMe(parameter, event){
}

<button onClick={this.clickMe.bind(this, someParameter)}></button>

+1 для параметра події, який є останнім у рішенні №2. Мені довелося усвідомити, що я роблю не так, я, мабуть, десь у документах пропустив причину.
abelito

5

Для повного вирішення проблеми створення зворотного виклику data-*найкращим рішенням IMO є використання атрибутів у HTML5. Оскільки в кінці дня, навіть якщо ви витягнете підкомпонент для передачі параметрів, він все одно створює нові функції.

Наприклад,

const handleBtnClick = e => {
  const { id } = JSON.parse(e.target.dataset.onclickparam);
  // ...
};

<button onClick={handleBtnClick} data-onclickparam={JSON.stringify({ id: 0 })}>

Див. Https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes щодо використання data-*атрибутів.


Мені подобається такий підхід. Просто і чисто
marknt15

5

Каррінг на прикладі ES6:

const clickHandler = param => event => {
  console.log(param); // your parameter
  console.log(event.type); // event type, e.g.: click, etc.
};

Наша кнопка, яка перемикає обробник:

<button onClick={(e) => clickHandler(1)(e)}>Click me!</button>

Якщо ви хочете викликати цей вираз функції без об'єкта події, тоді ви б назвали його таким чином:

clickHandler(1)();

Крім того, оскільки реакція використовує синтетичні події (обгортку для власних подій), існує подія об'єднання подій , що означає, що якщо ви хочете використовувати свій eventоб'єкт асинхронно, вам доведеться використовувати event.persist():

const clickHandler = param => event => {
  event.persist();
  console.log(event.target);
  setTimeout(() => console.log(event.target), 1000); // won't be null, otherwise if you haven't used event.persist() it would be null.
};

Ось прямий приклад: https://codesandbox.io/s/compassionate-joliot-4eblc?fontsize=14&hidenavigation=1&theme=dark


Навіщо мені ще потрібно мати event.persist()з , console.log(event)але мені не потрібно його console.log(event.target)?
Ісаак Пак


У цьому контексті швидше використовувати звичайну функцію, яка отримує 2 параметри, ніж каррі. Ви можете запустити контрольний тест у jsben.ch
ncesar

@ncesar Як налаштувати React у jsben.ch? Опублікуйте свій тест PLZ.
Ісаак Пак,

@IsaacPak jsben - це простий інструмент для тестування кодів JavaScript. Ви майже розміщуєте два різні зразки коду і порівнюєте їх швидкість. Вам не потрібно вводити весь код React, а лише функцію, яка, на вашу думку, може бути повільнішою і ви хочете протестувати. Крім того, я завжди використовую jsben.ch та jsbench.me лише для того, щоб переконатися. У контексті clickHandler вам потрібно буде знущатися над деякими кодами. Як, let event;отже, він не викличе невизначеної помилки.
ncesar
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.