Почему не работает onclick react

React JS onClick не может передать значение методу

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

мой код работает правильно. Когда я бегу, я вижу но не может получить его в событии onClick.

как я могу передать значение onClick событие в React js?

22 ответов

Легко

используйте функцию стрелки:

это создаст новую функцию, которая вызывает handleSort с нужными параметрами.

Лучше

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

если вы создаете субкомпонент, вы можете передать обработчик и использовать реквизит в качестве аргументы, которые затем будут повторно отображаться только при изменении реквизита (потому что ссылка обработчика теперь никогда не изменяется):

старый простой способ (ES5)

использовать .bind чтобы передать нужный параметр:

в настоящее время, с ES6, я чувствую, что мы могли бы использовать обновленный ответ.

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

[[h / t to @E. Sundin for связывая это в комментарии]

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

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

в ES5:

ЕС6:

и вы будете использовать его таким образом:

вот пример такого использования:

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

Edit:
Как предлагается в комментариях ниже, вы можете кэшировать / запоминать результат функции.

вот наивная реализация:

Это мой подход, не уверен, насколько это плохо, пожалуйста, прокомментируйте

в элементе clickable

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

обновление

в случае если вы хотите иметь дело с объектами, которые должны быть параметры. вы можете использовать JSON.stringify(object) преобразовать в строку и добавить в набор данных.

еще один вариант, не связанные .bind или ES6-использовать дочерний компонент с обработчиком для вызова родительского обработчика с необходимыми реквизитами. Вот пример (и ссылка на рабочий пример ниже):

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

Я написал компонент оболочки, который можно повторно использовать для этой цели, который основывается на принятых здесь ответах. Если все, что вам нужно сделать, это передать строку, а затем просто добавить атрибут данных и прочитать его из e.цель.dataset (как и некоторые другие). По умолчанию моя обертка будет привязываться к любой опоре, которая является функцией, и начинается с » on » и автоматически передает опору данных вызывающему объекту после всех других аргументов события. Хотя я не тестировал его на производительность, он будет дайте вам возможность избежать создания класса самостоятельно, и его можно использовать следующим образом:

const DataButton = withData(‘button’)

const DataInput = withData(‘input’);

или для компонентов и функций

const DataInput = withData(SomeComponent);

или, если вы предпочитаете

const DataButton = withData( )

объявите, что вне вашего контейнера (рядом с вашим импортом)

вот использование в контейнере:

вот код оболочки ‘ withData.js:

Я добавил код для передачи значения события onclick в метод двумя способами . 1 . использование метода bind 2. использование метода arrow (=>). см. методы handlesort1 и handlesort

делая альтернативную попытку ответить на вопрос OP, включая e.вызовы preventDefault ():

вынесено ссылке (ЕС6)

у меня есть ниже 3 предложения к этому на JSX onclick Events —

на самом деле, нам не нужно использовать .функция bind () или Стрелка в нашем коде. Вы можете просто использовать в своем коде.

вы также можете переместить событие onClick из th(или ul) в tr (или li), чтобы улучшить производительность. В основном у вас будет n количество «слушателей событий» для вашего элемента N li.

// и вы можете получить доступ к item.id на onItemClick метод, как показано ниже:

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

использование функции стрелки:

вы должны установить Этап-2:

npm установить babel-preset-stage-2:

есть 3 способа справиться с этим :-

привязать метод в конструкторе как : —

используйте функцию стрелки при ее создании как : —

Вы можете просто сделать это, если вы используете ES6 .

реализация показать общее количество от объекта путем передачи count в качестве параметра от main к sub компонентам, как описано ниже.

а вот SubComp.js

попробуйте реализовать выше, и вы получите точный сценарий, как параметры передачи работают в reactjs на любом методе DOM.

Ниже приведен пример, который передает значение события onClick.

я использовал синтаксис es6. помните, что функция стрелки компонента класса не связывается автоматически, поэтому явно связывается в конструкторе.

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

Источник

Обработка событий

Обработка событий в React-элементах очень похожа на обработку событий в DOM-элементах. Но есть несколько синтаксических отличий:

  • События в React именуются в стиле camelCase вместо нижнего регистра.
  • С JSX вы передаёте функцию как обработчик события вместо строки.

Например, в HTML:

В React немного иначе:

Ещё одно отличие — в React нельзя предотвратить обработчик события по умолчанию, вернув false . Нужно явно вызвать preventDefault . Например, в обычном HTML для отмены отправки формы (действие по умолчанию) можно написать:

В React это будет выглядеть так:

В приведённом выше коде e — это синтетическое событие. React определяет синтетические события в соответствии со спецификацией W3C, поэтому не волнуйтесь о кроссбраузерности. События React работают не совсем как нативные. Изучите руководство о SyntheticEvent , чтобы узнать о них больше.

При использовании React обычно не нужно вызывать addEventListener , чтобы добавить обработчики в DOM-элемент после его создания. Вместо этого добавьте обработчик сразу после того, как элемент отрендерился.

В компоненте, определённом с помощью ES6-класса, в качестве обработчика события обычно выступает один из методов класса. Например, этот компонент Toggle рендерит кнопку, которая позволяет пользователю переключать состояния между «Включено» и «Выключено»:

При обращении к this в JSX-колбэках необходимо учитывать, что методы класса в JavaScript по умолчанию не привязаны к контексту. Если вы забудете привязать метод this.handleClick и передать его в onClick , значение this будет undefined в момент вызова функции.

Дело не в работе React, это часть того, как работают функции в JavaScript. Обычно, если ссылаться на метод без () после него, например, onClick= , этот метод нужно привязать.

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

Такой синтаксис доступен в Create React App по умолчанию.

Если вы не пользуетесь синтаксисом полей, можете попробовать стрелочные функции в колбэке:

Проблема этого синтаксиса в том, что при каждом рендере LoggingButton создаётся новый колбэк. Чаще всего это не страшно. Однако, если этот колбэк попадает как проп в дочерние компоненты, эти компоненты могут быть отрендерены снова. Мы рекомендуем делать привязку в конструкторе или использовать синтаксис полей классов, чтобы избежать проблем с производительностью.

Передача аргументов в обработчики событий

Внутри цикла часто нужно передать дополнительный аргумент в обработчик события. Например, если id — это идентификатор строки, можно использовать следующие варианты:

Две строки выше — эквивалентны, и используют стрелочные функции и Function.prototype.bind соответственно.

В обоих случаях аргумент e , представляющий событие React, будет передан как второй аргумент после идентификатора. Используя стрелочную функцию, необходимо передавать аргумент явно, но с bind любые последующие аргументы передаются автоматически.

Источник

React js onClick не может передать значение методу

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

Мой код работает правильно. Когда я бегу, я вижу, но не могу получить его в событии onClick.

Как передать значение onClick событию в React js?

Простой способ

Используйте функцию стрелки:

Это создаст новую функцию, которая вызывает handleSort с правильными параметрами.

Лучший путь

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

Если вы создаете подкомпонент, вы можете передать обработчик и использовать реквизиты в качестве аргументов, которые затем будут перерисовываться только при изменении реквизитов (потому что ссылка на обработчик теперь никогда не меняется):

Старый легкий путь (ES5)

Используйте .bind для передачи желаемого параметра:

Здесь есть хорошие ответы, и я согласен с @Austin Greco (второй вариант с отдельными компонентами).
Есть еще один способ, который мне нравится — карри .
Что вы можете сделать, это создать функцию, которая принимает параметр (ваш параметр) и возвращает другую функцию, которая принимает другой параметр (в данном случае событие click). тогда вы можете делать с ним все, что захотите.

ES5:

ES6:

И вы будете использовать это так:

Вот полный пример такого использования:

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

Редактировать:
как предлагается в комментариях ниже, вы можете кэшировать / запоминать результат функции.

Вот наивная реализация:

В настоящее время, с ES6, я чувствую, что мы могли бы использовать обновленный ответ.

По сути, (для тех, кто не знает), поскольку onClick ожидает, что ему передана функция, bind работает, потому что он создает копию функции. Вместо этого мы можем передать выражение функции стрелки, которое просто вызывает функцию, которую мы хотим, и сохраняет this . Вам никогда не нужно связывать render метод в React, но если по какой-то причине вы проигрываете this в одном из ваших компонентных методов:

[[h / t к @ E.Sundin для того, чтобы связать это в комментарии]

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

Это объяснение оптимального способа сделать это из ESLint-plugin-реакции :

Обычный случай использования связывания при рендеринге — при рендеринге списка, чтобы иметь отдельный обратный вызов для каждого элемента списка:

Вместо того, чтобы делать это таким образом, перетащите повторяющийся раздел в его собственный компонент:

Это ускорит рендеринг, поскольку избавляет от необходимости создавать новые функции (посредством вызовов связывания) при каждом рендеринге.

Это мой подход, не уверен, насколько это плохо, пожалуйста, прокомментируйте

В кликабельном элементе

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

ОБНОВИТЬ

если вы хотите иметь дело с объектами, которые должны быть параметрами. Вы можете использовать, JSON.stringify(object) чтобы преобразовать его в строку и добавить в набор данных.

Еще одна опция, не включающая .bind или не использующая ES6, — это использование дочернего компонента с обработчиком для вызова родительского обработчика с необходимыми реквизитами. Вот пример (и ссылка на рабочий пример ниже):

Основная идея заключается в том, чтобы родительский компонент передавал onClick функцию дочернему компоненту. Дочерний компонент вызывает onClick функцию и может получить доступ к любому props переданному ей (и event ), что позволяет вам использовать любое event значение или другие реквизиты внутри родительского элемента. onClick .

Вот демонстрация CodePen, демонстрирующая этот метод в действии.

Попытка ответить на вопрос OP, включая вызовы e.preventDefault ():

Предоставленная ссылка ( ES6 )

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

Я полагаю, вы также можете использовать data- атрибут.

Просто создайте такую ​​функцию

и позвоните в нужное вам место

Вы можете просто сделать это, если вы используете ES6 .

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

А вот SubComp.js

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

Я написал компонент-обертку, который можно использовать повторно для этой цели, основываясь на принятых здесь ответах. Если все, что вам нужно сделать, это передать строку, однако, просто добавьте атрибут data и прочитайте его из e.target.dataset (как предлагали некоторые другие). По умолчанию моя обертка будет связываться с любым реквизитом, который является функцией, и начинается с ‘on’ и автоматически передает реквизит данных вызывающей стороне после всех других аргументов события. Хотя я не проверял его на производительность, он даст вам возможность избежать создания класса самостоятельно, и его можно использовать так:

или для компонентов и функций

или если вы предпочитаете

заявить, что за пределами вашего контейнера (около вашего импорта)

Вот использование в контейнере:

Вот код оболочки ‘withData.js:

У меня есть ниже 3 предложения на это на JSX onClick Events —

На самом деле нам не нужно использовать функцию .bind () или Arrow в нашем коде. Вы можете просто использовать в своем коде.

Вы также можете переместить событие onClick из th (или ul) в tr (или li), чтобы повысить производительность. В основном у вас будет n «прослушивателей событий» для вашего элемента n li.

// И вы можете получить доступ item.id к onItemClick методу, как показано ниже:

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

Я добавил код для передачи значения события onclick в метод двумя способами. 1 используя метод связывания 2. используя метод стрелки (=>). см. методы handlesort1 и handlesort

Ниже приведен пример, который передает значение на событие onClick.

Я использовал синтаксис es6. Помните, что в компоненте класса стрелка функция не связывается автоматически, поэтому явно связывается в конструкторе.

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

Это очень простой способ.

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

Используя функцию стрелки:

Вы должны установить этап 2:

npm установить babel-preset-stage-2:

Есть 3 способа справиться с этим:

Привязать метод в конструкторе как: —

Используйте функцию стрелки, создавая ее как: —

Третий способ заключается в следующем:

Вы можете использовать свой код следующим образом:

Здесь e для объекта события, если вы хотите использовать методы события, как preventDefault() в вашей функции handle, или хотите получить целевое значение или имя как e.target.name .

Я нашел решение передачи param в качестве атрибута тега довольно разумным.

Однако у него есть ограничения:

  • Не работает должным образом, когда элемент списка имеет другие теги (таким образом, event.target может отличаться от запланированного)
  • Param может быть только строкой. Требуется сериализация и десериализация.

Вот почему я придумал эту библиотеку: Reaction-Event-Param

  • Решает проблему детей путем поиска нужного атрибута у родителей при необходимости
  • Автоматически сериализует и десериализует param
  • Инкапсулирует логику установки и получения. Не нужно связываться с именами параметров

Было много соображений производительности, все в вакууме.
Проблема с этими обработчиками заключается в том, что вам нужно их карри, чтобы включить аргумент, который вы не можете назвать в реквизитах.
Это означает, что компоненту нужен обработчик для каждого кликабельного элемента. Давайте согласимся, что для нескольких кнопок это не проблема, верно?
Проблема возникает, когда вы обрабатываете табличные данные с десятками столбцов и тысячами строк. Там вы заметили влияние создания такого количества обработчиков.

Дело в том, что мне нужен только один.
Я устанавливаю обработчик на уровне таблицы (или UL или OL . ), и когда происходит щелчок, я могу определить, какая ячейка была нажата, используя данные, доступные с тех пор в объекте события:

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

Таким образом, мне не нужно передавать данные ячейки обработчику, он может самообслуживаться.
Если мне нужно больше данных, данных, которые не должны отображаться, я могу использовать атрибут набора данных или скрытые элементы.
С простой навигацией по DOM все под рукой.
Это используется в HTML с тех пор, как ПК было намного проще.

Есть несколько способов передать параметр в обработчиках событий, некоторые из них следующие.

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

Приведенный выше пример эквивалентен вызову .bind или вы можете явно вызвать bind.

Помимо этих двух подходов, вы также можете передавать аргументы в функцию, которая определена как функция карри.

Используйте закрытие , это приведет к чистому решению:

Функция handleSort вернет функцию с уже установленным столбцом значений .

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

Источник

Читайте также:  Как настроить длину пробела
Оцените статью