Почему обработчик событий элемента React JSX не использует круглые скобки, аналогичные обработчику событий html?

#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. Сценарий ухудшается в компоненте класса, когда обработчик событий изменяет состояние компонента, компонент постоянно перерисовывает и может видеть бесконечное количество сообщений в консоли.