не очень хорошая вещь, лучше сделать метод-прототип по соображениям совместимости,

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

Проблема, с которой я столкнулся, заключается в том, что синтетическая система событий React требует событий (например,onClick) быть обязанным реагировать на элементы DOM, какdiv, Если компонент, который я обертываю, является пользовательским компонентом, как и любой HOC, реализованный с помощью функции более высокого порядка, мои события щелчка не связываются правильно.

Например, используя этот HOC,onClick обработчик будет срабатывать для button1, но не для button2.

// Higher Order Component 
class Track extends React.Component {
  onClick = (e) => {
    myTracker.track(props.eventName);
  }

  render() {
    return React.Children.map(
      this.props.children,
      c => React.cloneElement(c, {
        onClick: this.onClick,
      }),
    );
  }
}

function Wrapper(props) {
  return props.children;
}

<Track eventName={'button 1 click'}>
  <button>Button 1</button>
</Track>

<Track eventName={'button 2 click'}>
  <Wrapper>
    <button>Button 2</button>
  </Wrapper>
</Track>

CodeSandbox с рабочим примером: https://codesandbox.io/embed/pp8r8oj717

Моя цель состоит в том, чтобы иметь возможность использовать такой HOF (необязательно в качестве декоратора) для отслеживания кликов по любому определению компонента React.

export const withTracking = eventName => Component => props => {
  return (
    <Track eventName={eventName}>
      {/* Component cannot have an onClick event attached to it */}
      <Component {...props} />
    </Track>
  );
};

Единственное решение, которое я могу придумать, это использоватьRef на каждого ребенка и вручную связывая мое событие клика как толькоRef населён.

Любые идеи или другие решения приветствуются!

ОБНОВИТЬ: С помощьюremapChildren Техника ответа @estus и более ручной способ рендеринга обернутых компонентов, я смог заставить это работать как функция более высокого порядка -https://codesandbox.io/s/3rl9rn1om1

export const withTracking = eventName => Component => {
  if (typeof Component.prototype.render !== "function") {
    return props => <Track eventName={eventName}>{Component(props)}</Track>;
  }
  return class extends Component {
    render = () => <Track eventName={eventName}>{super.render()}</Track>;
  };
};

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

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