Использование отслеживания событий реакции для создания контекста и запуска событий

Контекст React 16 обеспечивает отличную основу для построения фреймворка событий. Мы использовали эту возможность для создания реагирования-отслеживания событий, что позволяет приложениям и компонентам итеративно создавать информацию о событиях и запускать события там, где происходит активность пользователя. Это позволяет активировать компоненты перед включением приложений и проверять инициированные события во время тестирования, что приводит к согласованной обработке событий во всех приложениях.

История

В HomeAway мы используем специально разработанную платформу отслеживания событий для пользовательской аналитики. Одна из его функций - клиентский API для запуска событий, а также схема, определяющая эти события. Команда разработчиков использует эти функции для отслеживания активности пользователей в приложениях, инициируя события в различных точках иерархии DOM приложения.

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

Болезненная точка №1: общие компоненты не знают полного контекста

Общие компоненты знают, когда происходит событие (например, щелчок мышью или выбор), но они не знают всех деталей, необходимых для соответствия обязательным и необязательным полям (имя приложения, расположение на странице, идентификаторы свойств и т. Д.) пользовательское аналитическое событие. Это затрудняет запуск события, соответствующего схеме. Обычно это обходится либо путем передачи обязательных / необязательных полей по всей иерархии компонентов (фу!), Используя глобальные переменные (😱), либо с помощью общих компонентов, реализующих обратные вызовы и полагаясь на приложение-получатель для запуска события в реализованная функция. (Внимание, спойлер: все это нежелательно.)

Болезненная точка # 2: несогласованное срабатывание события

Работа над проблемой №1 с помощью обратных вызовов возлагает ответственность за запуск события на приложение-потребитель компонента. Это приводит к несогласованности в срабатывании событий, поскольку нет гарантии, что каждое приложение будет запускать событие.

Библиотечное решение

Помня о вышеуказанных проблемах, мы решили создать решение, которое позволило бы приложениям итеративно собирать информацию для события и позволить компоненту нижнего уровня инициировать событие с полным набором деталей. К счастью, React 16 формализовал понятие контекст:

Контекст предоставляет способ передавать данные через дерево компонентов без необходимости передавать реквизиты вручную на каждом уровне.

Используя контекст React 16 в качестве основы, мы построили реагирование-отслеживание событий. Репозиторий response-event-tracking предоставляет функциональные возможности для запуска событий, позволяя приложениям указывать дополнительные сведения, которые автоматически включаются в инициируемое событие. Это помогает обеспечить согласованность запуска событий в приложениях-потребителях, поскольку сам компонент запускает событие, а не полагается на приложение.

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

  1. Приложения используют TrackingProvider для определения реализации запуска события и обертывают компоненты, запускающие события, дополнительными полями и параметрами, которые будут объединены в инициируемое событие.
  2. Компоненты используют TrackingContext или TrackingTrigger для запуска событий, которые автоматически объединяют поля и параметры, указанные на более высоких уровнях DOM, через один или несколько TrackingProvider компонентов.

TrackingProvider

Компонент TrackingProvider позволяет приложению определять реализацию trigger события и постепенно создавать fields и options для событий, которые будут запускаться из вложенных компонентов. TrackingProvider - это поставщик контекста React 16, задуманный как универсальное решение, не требующее использования специальной аналитической библиотеки отслеживания событий.

import {TrackingProvider} from '@vrbo/react-event-tracking';
const defaultFields = {location: 'top-right'};
const defaultOptions = {asynchronous: true};
const customTrigger = (event, fields, options) => {
    // Implement custom event tracking.
}
function App(props) {
    return (
        <TrackingProvider 
            fields={defaultFields}
            options={defaultOptions}
            trigger={customTrigger}
        >
            // Events triggered by the Calendar component
            // will use the context specified above.
            <Calendar/>
        </TrackingProvider>
    );
}

Реализация триггера

Приложение отвечает за реализацию метода триггера через свойство trigger. Ожидается, что предоставленная реализация будет иметь следующую подпись:

trigger(event, fields, options)

Где:

  • событие - имя инициируемого события (строка).
  • поля - обязательные и необязательные поля для события (объект строковых значений).
  • параметры - параметры реализации настраиваемого триггера, которые будут использоваться при запуске события. (Объект - зависит от реализации)

Вложенность TrackingProvider

Несколько TrackingProvider компонентов могут быть вложены, чтобы многократно улучшать конфигурацию, в которой информация известна. Например, рассмотрим сценарий, в котором компонент Calendar из первого TrackingProvider примера выше использует компонент с именем EventButton, который запускает событие generic.click. Приложение может создавать поля, необходимые для generic.click, вкладывая TrackingProvider оболочки в области кода, которым известна соответствующая информация.

Вложенный компонент с дополнительными полями

import {TrackingProvider} from '@vrbo/react-event-tracking';
const buttonFields = {location: 'top-right'};
function CalendarButton(props) {
    return (
        <TrackingProvider fields={buttonFields}>
            <EventButton>{'Click Me'}</EventButton>
        </TrackingProvider>
    );
}

Когда EventButton запускает событие generic.click, обработчику триггера будет отправлен объединенный набор полей из экземпляров CalendarButton и приложения TrackingProvider.

TrackingContext

В то время как компонент TrackingProvider используется для постепенного создания полей и опций для события и определения реализации триггера, модуль TrackingContext используется для запуска аналитического события. TrackingContext - это объект контекста React 16, который используется для хранения значений полей и опций и предоставляет доступ к методу trigger для запуска событий. TrackingProvider и TrackingContext вместе позволяют приложению постепенно создавать поля и параметры, а затем запускать события на самом низком уровне. После настройки, как показано, компонент может получить доступ к методу trigger через this.context.trigger.

import React, {Component} from 'react';
import {TrackingContext} from '@vrbo/react-event-tracking'
class MyComponent extends Component {
    static contextType = TrackingContext;
    handleClick() {
        this.context.trigger(`generic.click`);
    }
    ...
}

В качестве альтернативы, если приложение было обновлено до React ›16.8.0, для доступа к методу триггера можно использовать useContext hooks api.

TrackingTrigger

Компонент TrackingTrigger позволяет приложению декларативно запускать событие отслеживания. Он используется вместе с компонентом TrackingProvider для запуска событий стандартным способом. Укажите желаемое имя события, поля и параметры, которые необходимо включить при срабатывании события. Событие будет инициировано слиянием указанных полей и опций и текущего контекста при вызове componentDidMount компонента.

import {TrackingTrigger} from '@vrbo/react-event-tracking';
const eventFields = {
    location: 'searchbar',
    name: 'SomeComponent'
};
const eventOptions = {asynchronous: true};
function SomeComponent(props) {
    return (
        ...
        <TrackingTrigger
            event={'visible'}
            fields={eventFields}
            options={eventOptions}
        />
    );
}

Подтверждение события

В HomeAway наша платформа отслеживания событий пользовательской аналитики исторически не отклоняла события, которые являются недопустимыми в соответствии со схемой. Эта стратегия упрощает процесс запуска событий и предотвращает появление ошибок в приложениях. Однако это привело к тому, что в систему поступают неверные данные, которые необходимо очистить перед анализом. Чтобы способствовать запуску событий в соответствии со схемой, мы создали компонент-оболочку вокруг TrackingProvider, который обеспечивает реализацию метода trigger, который проверяет запросы событий на соответствие нашей аналитической схеме событий. Эшафот для настройки поставщика проверки может быть таким же простым, как показано ниже:

import React, {Component} from 'react';
import {TrackingProvider} from '@vrbo/react-event-tracking';
class TrackingProviderValidator extends Component {
  trigger = (event, fields = {}, options = {}) => {
    // Add implementation specific code to validate the event,
    // fields and options against your schema. Throw an exception
    // or use some other means to cause unit tests to fail if
    // not valid
  }
  render() {        
    return (
      <TrackingProvider
        {...this.props}               
        trigger={this.trigger}
      >
        {children}
      </TrackingProvider>
    );
  }
}

Затем мы используем этого поставщика проверки в наших модульных тестах, чтобы убедиться, что события, запускаемые компонентом, действительны в соответствии со схемой.

Предостережения

  1. Для использования contextType в компоненте React требуется react: ^16.6.0.
  2. До React 16.8.0 компонент не мог использовать несколько contextType определений. Если компоненту необходимо использовать несколько контекстов, используйте useContext hooks API, доступный в React 16.8.0.
  3. Если TrackingProvider с реализацией trigger не определен где-то в иерархии, API-интерфейс триггера по существу не работает. Это позволяет компонентам активировать запуск событий независимо от того, настроено ли приложение для их запуска.
  4. Мы рекомендуем, чтобы значения свойств для TrackingProvider определялись в переменных состояния или констант вместо того, чтобы создавать значения динамически при каждой визуализации. Если значения создаются во время визуализации, это вызовет принудительную повторную визуализацию всех потребителей контекста, которые являются потомками поставщика, даже если потребитель shouldComponentUpdate выскакивает. Следование шаблону определения значений свойств как констант или через состояние предотвратит ненужную визуализацию дочерних потребителей контекста.

Резюме

Создание общего набора компонентов в React, который используется в широком спектре приложений, экономит время разработчика за счет повторного использования кода, а также способствует единообразию внешнего вида. Пользовательские аналитические данные, создаваемые этими компонентами, также должны быть согласованными, однако было трудно добиться и обеспечить эту согласованность, когда каждое приложение определяет, когда запускаются события. Response-event-trackin g предоставляет через контекст React 16 средство для приложений, чтобы предоставить необходимые детали, но позволяет общим компонентам запускать события там, где они происходят. Мы надеемся, что другие команды сочтут отслеживание событий реакции полезным, и с нетерпением ждем ваших отзывов и вкладов в проект с открытым исходным кодом.