3

As I understand it ES6 arrow functions "preserve this context when they are called." I have seen examples in React components using them to bind this in class methods. I know I can bind in the constructor like this:

constructor(props) {
    super(props);
    this.getContent = this.getContent.bind(this);
    this.handleClick = this.handleClick.bind(this);
}

But when I try to use an arrow function

handleClick = (event) => {
    this.props.openForm();
}

I get the following error

Module build failed: SyntaxError: Unexpected token (18:14)

  16 |   }
  17 | 
> 18 |   handleClick = (event) => {
     |               ^
  19 |     this.props.openForm();
  20 |   }
  21 | 

Why isn't this working?

Here's the full component

import React from 'react';
import Section from './Section';
import { connect } from 'react-redux';
import * as actions from '../actions/actions';

class Contact extends React.Component {

  getContent() {
    return this.props.content || {};
  }

  handleClick = (event) => {
    this.props.openForm();
  }

  render() {
    return (
      <Section heading="Contact" bg="white">

          <div className="contact">

            <h3 className="contact__heading">{ this.getContent().heading }</h3>

            <p>{ this.getContent().text }</p>

            <button className="contact__button contact__btn-dialog" 
                onClick={ this.handleClick }>
              Send a message
            </button>

          </div>

      </Section>
    );
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    openForm: () => {
      dispatch(actions.showContactForm(true));
    }
  };
};

export default connect(
  null,
  mapDispatchToProps
)(Contact);
mhatch
  • 4,441
  • 6
  • 36
  • 62
  • Also see on bind vs arrow property, https://stackoverflow.com/a/43601993/3731501 – Estus Flask Oct 10 '17 at 19:59
  • It isn't concidental that these questions share a topic. Dupe question has *exactly* same problem, and [the cause and the solution](https://stackoverflow.com/a/41464305/3731501) should be same, too. Consider re-asking the question with updated details if the solution suggested in dupe question didn't work for you. – Estus Flask Feb 14 '18 at 17:11
  • I was looking at the link in the comments stackoverflow.com/a/43601993/3731501 I later saw the link at the top and realized the error. – mhatch Feb 14 '18 at 17:13

1 Answers1

1

If you declare the method as arrow function you don't need to bind it in the constructor.

In this case, use either bind or arrow function directly and not both.

class App extends React.Component {
  constructor() {
    super()

    this.handleClick = this.handleClick.bind(this)
  }

  handleClick() {
     console.log('with constructor')
  }
  
  handleClick2 = (event) => {
    console.log('without constructor')
  }

  render() {
    return (
      <div>
        <button onClick={this.handleClick}>With constructor</button>
        <button onClick={this.handleClick2}>Without constructor</button>
      </div>
    )
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="root"></div>
Hemerson Carlin
  • 7,354
  • 1
  • 27
  • 38
  • I do not have it in the constructor, if you will look at the full component in the OP. `this` evaluates to null. I get the error "Uncaught TypeError: Cannot read property 'props' of null" – mhatch Oct 10 '17 at 20:00
  • @mhatch Please check my sample code. Maybe that helps :) – Hemerson Carlin Oct 10 '17 at 20:05