почему вам нужно связать функцию в конструкторе
У меня есть вопрос, связанный с этим кодом: https://github.com/reactjs/redux/blob/master/examples/async/containers/App.js
в частности:
constructor(props) {
super(props)
this.handleChange = this.handleChange.bind(this)
this.handleRefreshClick = this.handleRefreshClick.bind(this)
}
Я думаю, это вопрос из двух частей.
- Почему мне нужно установить изменение дескриптора в качестве экземпляра класса
this.handleChange =
, не могу ли я просто использовать статические функции для handleChange и вызывать его напрямую в классе onClick={handleRefreshClick}>
? - Я понятия не имею, что здесь происходит:
this.handleRefreshClick.bind(this)
благодаря
Ответы
Ответ 1
Ответил в обратном порядке...
-
this.handleRefreshClick.bind(something)
возвращает новую функцию, в которой ссылки на this
будут ссылаться на something
. Это способ сохранить текущее значение this
, которое находится в области видимости во время вызова конструктора, так что его можно использовать позже, когда вызывается функция.
- Если ваши функции не требуют доступа к состоянию вашего компонента, то, конечно, вам не нужно связывать их.
Аргумент в пользу добавления этих строк в конструктор заключается в том, что новые связанные функции создаются только один раз для экземпляра класса. Вы также можете использовать
onClick={this.handleRefreshClick.bind(this)}
или (ES6):
onClick={() => this.handleRefreshClick()}
но любой из этих методов будет создавать новую функцию каждый раз, когда компонент повторно отображается.
Ответ 2
Эти 2 функции handleChange и handleRefreshClick передаются как реквизиты для других компонентов,
Они привязаны к этому, потому что, когда дочерний компонент будет вызывать эти функции, они всегда будут выполняться в контексте APP.
Вы можете удалить эти функции из класса, но все же вам нужно связать это, поскольку вы будете обновлять некоторые части вашего APP
Ответ 3
Причина, по которой это делается, заключается в привязке this
ключевого слова к этому объекту. Как сказал Том, вызов функции из класса не означает, что он вызывается с контекстом объекта, который создал эту функцию.
Я думаю, вы могли бы путаться, потому что в React примеры/учебники, используя React.createClass() не связывают this
автоматически. Поэтому вам может быть интересно, почему React.createClass() делает это, но не с синтаксисом класса ES6.
Это связано с тем, что React не хотел возиться со спецификациями ES6 (привязка this
к функциям от его класса не относится к спецификации класса ES6), но в то же время хотела дать своим пользователям удобство синтаксиса класса ES6. Вы можете прочитать об этом ниже.
Вопрос Github
Надеюсь, это проливает свет на то, почему это происходит.
Ответ 4
this
зависит от того, как вызывается функция, а не от того, как и где она создана.
Когда вы смотрите на код, вы видите два "это", почему? Кажется странным, верно?
Дело не в том, как кажется. Это о том, как это называется.
Вы в основном говорите. Эй, когда кто-то звонит, ты помнишь this
означает этот класс. не что-то еще.
Когда кто-то называет ваш класс следующим образом: x.yourClass().bind(this)
вы говорите, что this
- это не x
, а сам класс (с реквизитами, состояниями и т.д.).
Заметьте, что даже когда вы вызываете класс прямо, как yourClass()
, вы на самом деле вызываете window.yourClass()
в браузере, поэтому в этом случае это окно.
Ответ 5
Я лично связываю функции в конструкторе, чтобы их ссылки не менялись при каждом повторном рендеринге.
Это особенно важно, если вы передаете функции детям только для чтения, которые вам не нужно обновлять, когда их реквизиты не меняются. Для этого я использую add-addons-pure-render-mixin.
В противном случае, при каждом повторном рендеринге родителя будет происходить связывание, будет создана и передана новая функция ссылки на детей, которая будет думать, что реквизит изменился.