title: Can I use a higher order component to add an onClick to my component without adding a wrapper DOM element?
body: <p>We're moving an existing application for a specific touch screen to React. The screen has some sensitivity issues so we want to customise the <code>onClick</code> behaviour of all the tappable components like buttons etc. For example, we want the <code>onClick</code> to also fire if the user presses the button and then moves his finger out of the button before letting go. </p>
  
  <p>In general, we need to add some state to all tappables and I thought a <a href="https://reactjs.org/docs/higher-order-components.html" rel="nofollow noreferrer">Higher Order Component</a> would be ideal for this, so I made the following: </p>
  
  <p><strong>HOC</strong></p>
  
  <pre><code>const withTouchable = WrappedComponent =&gt; {
      return class Touchable extends React.Component {
          onClick() {
              this.props.onClick();
          }
  
          onMouseLeave() {
              // Some complicated logic to determine if we want to fire onClick
              if(...) {
                  this.props.onClick();
              }
          }
  
          // Other mouse and touch handlers
          // onMouseMove = ...
  
          render() {
              return (
                  &lt;WrappedComponent
                      {...this.props}
  
                      onClick={this.onClick.bind(this)}
                      onMouseLeave={this.onMouseLeave.bind(this)}
  
                      // other mouse and touch handlers
                  /&gt;
              );
          }
      };
  };
  </code></pre>
  
  <p><strong>Sample component we want to be clickable.</strong></p>
  
  <pre><code>const Heading = ({ title }) =&gt; &lt;h1&gt;{title}&lt;/h1&gt;;
  </code></pre>
  
  <p><strong>Sample app</strong></p>
  
  <pre><code>const TouchableHeading = withTouchable(Heading);
  
  class App extends React.Component {
  
      onClick() {
          console.log("title tapped")
      }
  
      render() {
          return (
              &lt;TouchableHeading
                  title="Some title"
                  onClick={this.onClick.bind(this)}
              /&gt;
          );
      }
  }
  
  ReactDOM.render(&lt;App /&gt;, document.getElementById("root"));
  </code></pre>
  
  <p>Unfortunately this does not work, because although the <code>&lt;WrappedComponent&gt;</code> is returned with mouse and touch handlers, this is not used by the <code>&lt;Heading&gt;</code>. See <a href="https://codepen.io/anon/pen/bvgZwb" rel="nofollow noreferrer">codepen.io/bvgZwb</a></p>
  
  <p>An alternative would be to wrap a div around the WrapperComponent:</p>
  
  <pre><code>render() {
      return (
          &lt;div
              onClick={this.onClick.bind(this)}
              onMouseLeave={this.onMouseLeave.bind(this)}
              // other mouse and touch handlers
          &gt;
              &lt;WrappedComponent {...this.props}/&gt;
          &lt;/div&gt;
      );
  }
  </code></pre>
  
  <p>See <a href="https://codepen.io/anon/pen/xWgBMJ" rel="nofollow noreferrer">codepen.io/xWgBMJ</a>. But this adds an extra DOM element, which is not ideal (it messes with the styling and there is no time to rewrite the whole app). </p>
  
  <p>Is there another way I'm not thinking about to achieve this? I did look into <a href="https://codedaily.io/tutorials/6/Using-Functions-as-Children-and-Render-Props-in-React-Components" rel="nofollow noreferrer">render props and using functions as children</a> but I don't think it's possible to achieve my goal that way. </p>
  
  <p>Note: Don't mind the <code>this.onClick.bind(this)</code>, <a href="https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md" rel="nofollow noreferrer">I know</a>. </p>