В документах React страница обработки событий сказано:
Generally, if you refer to a method without () after it, such as onClick = {this.handleClick}, you should bind that method.
Мне не ясна разница между onClick = {this.handleClick}
и onClick = {this.handleClick()}
или почему использование ()
означает, что вам не нужно связывать this
.
Любая помощь в понимании будет принята с благодарностью.
Никогда не используйте onClick = {this.handleClick()}
. Это не сработает (независимо от того, привязывается ли оно this
или нет). Либо используйте onClick = {this.handleClick.bind(this)}
, либо onClick = {e => this.handleClick(e)}
. Чтобы было ясно: совет из документов не предполагает, что вы можете использовать this.handleClick()
или что вам не нужно привязывать this
, если вы это сделаете. Опять же, onClick = {this.handleClick()}
всегда плохо.
Я все еще в замешательстве, потому что кажется, что он также называется без ()
(пока this
связан). В примере на странице обработки событий, на которую я ссылался, {this.handleClick}
, кажется, вызывает метод handleClick()
, определенный в классе. Я нигде не вижу handleClick()
.
Это не относится к React и не имеет ничего общего с привязкой. Вот простой пример JS: jsfiddle.net/хрисмук/23nmurt4
I don't see handleClick() anywhere.
Вы назначили this.handleClick
на onClick
, поэтому, когда React вызывает element.onClick()
, именно тогда вызывается this.handleClick()
.
this.handleClick
относится к функции. this.handleClick()
вызывает эту функцию.
Дело не столько в том, что использование ()
устраняет необходимость привязки, просто в контексте вызова this.handleClick()
javacript «знает», на что this
должен ссылаться.
Итак, если я позвоню:
this.handleClick();
Из контекста ясно, что такое this
.
Но если я позвоню
const foo = this.handleClick;
foo();
Я все еще вызываю ту же функцию, но исходная ссылка на this
исчезла.
Что касается «почему». Я не знаю исторической причины этого, но это побочный эффект того, как был определен Javascript. Язык javascript, вероятно, был бы немного лучше, если бы это было не так, но так работает язык. Я не уверен, что это удовлетворительный ответ.
При воздействии на ссылку функции на новую переменную контекст (на который указывает this
внутри этой функции) не копируется.
В приведенном ниже фрагменте функция sayHi использует this
. Объект, на который он ссылается, изменяется в зависимости от того, как он вызывается или связывается.
const jack = {
name : 'Jack',
saysHi : function() {
console.info("Hi, I'm " + this.name);
}
};
jack.saysHi(); // this will reference jack
const someoneSaysHi = jack.saysHi;
someoneSaysHi(); // this will not reference jack anymore, but the global object window
const joe = { name : "Joe" };
const joeSaysHi = someoneSaysHi.bind(joe);
joeSaysHi(); // this will reference joe, because you bound the function to joe
jack.saysHi()
это будет ссылка на jack
. Я вызываю функцию с помощью . оператор, вызывая его в контексте объекта jack
.const someoneSaysHi = jack.saysHi ;
, а затем вызвав someoneSaysHi ()
, я вызываю его без всякого контекста. Таким образом, this
будет ссылкой на глобальный объект window
. Это особенность языка.someoneSaysHi
к контексту joe, я создаю новую функцию, и в этой функции this будет ссылкой на joe
.Более полный ответ: Как работает ключевое слово «это»?
Теперь о вашей проблеме:
Generally, if you refer to a method without () after it, such as onClick = {this.handleClick}, you should bind that method.
Атрибуту onClick требуется ссылка на функцию для присоединения к событию клика.
onClick = {this.handleClick()}
немедленно вызовет this.handleClick
(с правильным контекстом) и прикрепит событие клика к возвращаемому значению функции this.handleClick
.onClick = {this.handleClick}
без привязки чего-либо прикрепит событие клика к функции handleClick
, но в этом контексте this
внутри вашей функции handleClick
будет текущей целью события (элемент, на который вы нажали) — это функция обработчиков событий.onClick = {this.handleClick.bind(this)}
прикрепит событие click к новой ссылке на функцию, привязанной к объекту, на который ссылается this
.
()
означает, что вы хотите немедленно вызов функцию и использовать любое значение, которое она возвращает.