предоставляет более актуальную информацию и дальнейшее чтение.

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

Взгляните на эти две части кода:

class demo extends React.component {
  goToStore(event) {
    console.log(this)
  }

  render() {
    <button onClick={(e) => this.goToStore(e)}>test</button>
  }
}

против

class demo extends React.component {
  goToStore(event) {
    console.log(this)
  }

  render() {
    <button onClick={this.goToStore}>test</button>
  }
}

Что я знаю, так это:

в обеих версиях мы успешно заканчиваем в методе goToStore, потому чтоthis внутриrender() метод автоматически связывается (с помощью React) с экземпляром компонентапервый из-за этоговторой сбой, потому что методы класса в es6 не привязаны к экземпляру компонента, что позволяетthis в методеundefined

Теоретически в первом варианте, насколько я понимаю, происходит следующее:

обработчик нажатия кнопки является анонимнымстрелка функция, поэтому всякий раз, когда я ссылаюсьthis внутри он поднимаетсяthis из окружающей среды (в данном случае изrender())тогда он вызываетgoToStore метод, это регулярная функция.потому что вызов, кажется, соответствует правилам неявного связывания (object.function()) object будет объектом контекста, и в таких вызовах функций он будет использоваться какthisтак, внутриgoToStore Метод лексически подобранный (используемый как объект контекста) правильно разрешит экземпляр компонента

Я чувствую, что 3. и 4. здесь не тот случай, потому что тогда это относится к случаю 2.:

<button onClick={this.goToStore}>test</button>

Также сthis контекстный объект.

Что происходит именно в этом конкретном случае, шаг за шагом?

Ответы на вопрос(3)

this ссылается на класс компонента, поэтому он может ссылаться на правильную функцию. Это значит, чтоelement.onClick указывает наgoToStore метод.

Когда эта функция вызывается в браузере, она вызывается из контекста элемента html (т.е.element.onClick()). Так что еслиgoToStore Метод связан с контекстом класса компонента, он наследуетthis из контекста элемента.

Этот ответ предоставляет более актуальную информацию и дальнейшее чтение.

Решение Вопроса

Функция стрелки не имеет своего собственного this; это значение окружающего контекста исполнения используется

Так что вы бы подумали о

onClick={(e) => this.goToStore(e)}

как анонимная функция, которая может быть записана как

    (e) => { 
         return this.goToStore(e) 
    }

Теперь вот в этой анонимной функцииthis ссылается на лексический контекст функции рендеринга, который, в свою очередь, ссылается на экземпляр класса React.

В настоящее время

контекст чаще всего определяется тем, как вызывается функция. Когда функция вызывается как метод объекта, это устанавливается для объекта, для которого вызывается метод:

var obj = {
    foo: function() {
        return this;   
    }
};

obj.foo() === obj; // true

Тот же принцип применяется при вызове функции с оператором new для создания экземпляра объекта. Когда вызывается таким способом, значение этого в пределах области функции будет установлено во вновь созданный экземпляр:

function foo() {
    alert(this);
}

foo() // window
new foo() // foo

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

Так вот, так как функция называется какthis.goToStore() это внутри будет ссылаться на контекст компонента React.

Однако, когда вы пишетеonClick={this.goToStore}функция не выполняется, но ссылка на нее присваивается функции onClick, которая затем вызывает ее, вызываяthis быть неопределенным внутри функции, так как функция выполняется в контекстеwindow объект.

Теперь, хотяonClick={(e) => this.goToStore(e)} работает, когда вызывается render, создается новый экземпляр функции. В вашем случае этого легко избежать, просто создав функцию goToStore с использованием синтаксиса функции стрелки.

goToStore = (e) => {

}

Проверьте документы для более подробной информации оthis

 marchello07 дек. 2017 г., 10:03
Теперь я понимаю, что позже, когда происходит щелчок, ссылка на функцию вызывается простым вызовом функции, например:onClick(), что приводит к правилу привязки по умолчанию, то есть окну. Спасибо!

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

По сути, во втором примере все, что вы делаете, это что-то вроде этого:

function demo() {
   // this is the constructor
}
demo.prototype.goToStore = function() {
  // handler
};
demo.prototype.render = function() {
  return React.createElement('button', onClick: this.goToStore);
}

Как видите,onClick свойство просто получает ссылку на функцию. Всякий раз, когда эта функция вызывается, нетthis будет связан, и он будет запущен в контекстеwindow объект.

В старых библиотеках, до появления современных транспортеров, мы делали что-то вроде этого ВСЕ НА МЕСТЕ:

function demo() {
   // this is the constructor     
   this.goToStore = this.goToStore.bind(this);
   // same for every other handler
}
demo.prototype.goToStore = function() {
   // handling code.
};
demo.prototype.render = function() {
  // this goToStore reference has the proper this binded.
  return React.createElement('button', onClick: this.goToStore);
}

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

class demo extends Anything {
  constructor() {
  }
  bindedMethod = () => {
    // my context will always be the instance!
  }
}

С небольшими различиями все перевозчики переместят определениеbindedMethod в конструктор, гдеthis будет привязан к текущему экземпляру, выполняющему конструктор.

 marchello07 дек. 2017 г., 10:06
Спасибо, теперь я понимаю. Ваш ответ был так же хорош, как и ответ от Шубхам, я бы его тоже принял, если бы ему было позволено принять два ответа.

Ваш ответ на вопрос