#javascript #html #reactjs
#javascript #HTML #reactjs
Вопрос:
Изучая обработчики событий HTML, а затем React, я понял, что в HTML значение обработчика событий, например, функция, должно сопровождаться круглыми скобками. Насколько я понимаю, элементы JSX — это еще один способ написания html-подобных элементов в React, но при написании этих элементов мы должны опускать круглые скобки, и я не могу понять почему? разве они не должны вести себя так же, если они представляют элементы, подобные HTML?
<button onClick={shoot}>JSX element!</button>
<button onclick="shoot()">HTML element!</button>
Ответ №1:
Код между {
и }
в JSX является выражением JavaScript. Значение, передаваемое обработчику React onClick
, должно быть функцией.
So onClick={foo}
эквивалентно addEventListener("click", foo);
Но onClick={foo()}
эквивалентно addEventListener("click", foo());
. Выражение foo()
вызовет foo
функцию и разрешит ее возвращаемое значение. Это нормально, если foo
возвращает другую функцию, и бесполезно, если это не так.
Значение onclick
атрибута HTML представляет собой строку (все значения атрибута являются строками), которая вычисляется как тело функции.
Так onclick="foo()"
что (очень грубо, потому что внутренние атрибуты события также делают странные вещи с областью видимости) эквивалентно addEventListener("click", new Function("foo()");
С другой стороны, функция, которая просто упоминает foo
, ничего не сделает.
function foo() {
console.log("I've been called!");
}
function onClick() {
foo;
}
onClick();
Комментарии:
1. Также в примере HTML вместо
onclick="foo()"
того, чтобы быть обернутым в другую функцию в качестве аргумента addEventListener , почему это не простоonclick="foo"
, а затем его можно просто передать без необходимости быть обернутым в другую функцию?2. Потому что он не был разработан таким образом.
Ответ №2:
Итак, допустим, у нас есть функция
const shoot = () => { };
вот как мы его выполняем
shoot(); // this will execute the function
и теперь это то, как мы привязываем функцию к событию, мы не вызываем ее like document.addEventListener('click', shoot());
, мы просто передаем ссылку на функцию, поэтому, когда произойдет событие, функция будет выполнена.
document.addEventListener('click', shoot); // shoot will execute when click on tghe document
Теперь это вызовет shoot()
, когда этот элемент присоединяется к dom, потому что это shoot()
, поэтому мы запускаем его мгновенно
<button onclick="shoot()">HTML element!</button>
Но это вызовет, когда произойдет щелчок, почему? мы передаем ссылку на функцию, поэтому, когда происходит щелчок js, может вызвать функцию
<button onClick={shoot}>JSX element!</button>
Ответ №3:
Обработчик событий элемента React JSX не использует круглые скобки, потому что обработчик событий является функцией, а не вызовом функции. например —
import React from 'react'
function FunctionClick() {
function clickHandler(){
console.log("button clicked")
}
return (
<div>
<button onClick={clickHandler}>Click</button>
</div>
)
}
export default FunctionClick
Если мы добавим круглые скобки после обработчика событий, то сообщение консоли уже будет зарегистрировано в выводе без нажатия кнопки click. Сценарий ухудшается в компоненте класса, когда обработчик событий изменяет состояние компонента, компонент постоянно перерисовывает и может видеть бесконечное количество сообщений в консоли.