Автор оригинала: Cory House.
JavaScript’s это Поведение ключевых слов смущает разработчиков для веков.
Есть как минимум пять способов обработки это контекст в реакции. Давайте рассмотрим достоинства каждого подхода.
1. Используйте RECT.CREATECLASS.
Если вы используете Rect.CreateClass , React Autobinds все функции для это Отказ Итак, это Ключевое слово привязано к экземпляру вашего компонента автоматически:
// This magically works with React.createClass// because `this` is bound for you.onChange={this.handleChange}
Однако с появлением классов ES6 этот нестандартный подход к созданию классов не будущее реагирования. На самом деле, CreateClass, вероятно, будет извлечен из ядра React в будущем Отказ
2. Связывать в визуализации
Остальные из этих подходов предполагают, что вы объявляете реактивные компоненты через классы ES6. Если вы используете класс ES6, не реагируйте больше не автобиды. Один из способов решить это, чтобы позвонить привязку в визуализации:
onChange={this.handleChange.bind(this)}
Этот подход расследует и ясно, однако, есть последствия для производительности, поскольку функция перераспределяется на каждом визуализации. Это звучит как большая сделка, но Последние последствия этого подхода вряд ли будут заметны в большинстве приложений. Таким образом, решение этого в начале по причинам эффективности – преждевременная оптимизация. Что сказал, Вот пример, где разумное влияние этого подхода .
Дендровя, если вы испытываете проблемы с производительностью, Избегайте использования функций связывания или стрелки в визуализации Отказ
3. Используйте функцию стрелки в рендере
Этот подход похож на # 2. Вы можете избежать изменения это Контекст с помощью функции стрелки в рендере:
onChange={e => this.handleChange(e)}
Этот подход имеет то же потенциальное воздействие эффективности как № 2.
Альтернативные подходы ниже того стоит рассмотреть, поскольку они предлагают превосходные показатели для небольших дополнительных затрат.
4. Связываться в конструкторе
Один из способов избежать связывания в визуализации состоит в том, чтобы связать в конструкторе (другой подход обсуждается в # 5 ниже).
constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); }
Это подход В настоящее время рекомендуется в реагированных документах Для «Лучшая производительность в вашем приложении». Это также подход, который я использую в разделе « | Построение приложений с реагированием и redux в ES6 » на Pluralsight.
Тем не менее, на большинстве приложений последствия производительности подхода № 2 и № 3 не будут заметны, поэтому достоверность и преимущества читаемости и обслуживания подхода № 2 и № 3 может перевесить проблемы со стороны производительности во многих приложениях.
Но если вы готовы использовать функции Stage-2, окончательный вариант ниже, скорее всего, ваша лучшая ставка.
5. Используйте функцию стрелки в свойстве класса
Эта техника опирается на Предлагаемый класс объекта недвижимости Отказ Чтобы использовать этот подход, вы должны включить Преобразование-классовые свойства или Включить этап 2 в Вавиле Отказ
handleChange = () => { // call this function from render // and this.whatever in here works fine. };
Этот подход имеет несколько преимуществ:
- Функции стрелки Принять это Привязка приложений охвата (Другими словами, они не меняют смысл это), Так что все просто работает автоматически.
- Это позволяет избежать вопросов производительности подходов № 2 и № 3.
- Это позволяет избежать повторения в подходе № 4.
- Это просто для рефактора из стиля ES5 CreateClass в этот стиль, преобразуя соответствующие функции в функции стрелки. На самом деле, есть Полностью автоматизированный способ справиться с этим используя кодемод.
Резюме
Эта блок-схема, которая подводит подсчет решения.
Вот полные рабочие примеры всех 5 подходов:
// Approach 1: Use React.createClass var HelloWorld = React.createClass({ getInitialState() { return { message: 'Hi' }; }, logMessage() { // this magically works because React.createClass autobinds. console.log(this.state.message); }, render() { return ( ); } }); // Approach 2: Bind in Render class HelloWorld extends React.Component { constructor(props) { super(props); this.state = { message: 'Hi' }; } logMessage() { // This works because of the bind in render below. console.log(this.state.message); } render() { return ( ); } } // Approach 3: Use Arrow Function in Render class HelloWorld extends React.Component { constructor(props) { super(props); this.state = { message: 'Hi' }; } logMessage() { // This works because of the arrow function in render below. console.log(this.state.message); } render() { return ( this.logMessage()} /> ); } } // Approach 4: Bind in Constructor class HelloWorld extends React.Component { constructor(props) { super(props); this.state = { message: 'Hi' }; this.logMessage = this.logMessage.bind(this); } logMessage() { // This works because of the bind in the constructor above. console.log(this.state.message); } render() { return ( ); } } // Approach 5: Arrow Function in Class Property class HelloWorld extends React.Component { // Note that state is a property, // so no constructor is needed in this case. state = { message: 'Hi' }; logMessage = () => { // This works because arrow funcs adopt the this binding of the enclosing scope. console.log(this.state.message); }; render() { return ( ); } }
Так что люди предпочитают? Вот опрос:
Как вы справляетесь с привязкой в #reaCtjs Cегодня? Примеры: https://t.co/z7okxe39VA
Есть другие способы справиться с этим? Пожалуйста, звоните через комментарии.
Огромное спасибо @dan_abramov , @kentcdodds и @dmosher Для их ценного ввода и рассмотрения!
Дом Кори Является ли автор « построение приложений с реагированием и redux в ES6 », « Строительные приложения с реагированием и потоком », « Clean Code: Написание кода для людей «И несколько других курсов по множеству. Он является архитектором программного обеспечения в Vinsolutions, Microsoft MVP и Поезда разработчиков программного обеспечения на международном уровне О программных методах, таких как интерфейс разработки и чистого кодирования.
Оригинал: “https://www.freecodecamp.org/news/react-binding-patterns-5-approaches-for-handling-this-92c651b5af56/”