Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Arrow function "this" binding not working in React component [duplicate]

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);
like image 468
mhatch Avatar asked Nov 22 '25 16:11

mhatch


1 Answers

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>
like image 69
mersocarlin Avatar answered Nov 24 '25 07:11

mersocarlin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!