[OnsenUI2/React] React Component: Event handler looses "this" context



  • I have a component that looks like this:

    import React, { Component, PropTypes } from 'react';
    import ons from 'onsenui';
    import { Row, Col } from 'react-onsenui';
    
    export class Result extends Component {
        handleClick() {
            ons.notification.alert( this.props.result._id );
        }
    
        render() {
            return (
                <Col onClick={this.handleClick}>{this.props.result.text}</Col>
            );
        }
    }
    

    This should work in plain React, because this is the component instance in the event handler.
    But it fails with OnsenUI2, because when the handleClick() event handler is called, I have lost my this data context.

    I can make it work by doing

    import React, { Component, PropTypes } from 'react';
    import ons from 'onsenui';
    import { Row, Col } from 'react-onsenui';
    
    export class Result extends Component {
        handleClick(result) {
            ons.notification.alert( result._id );
        }
    
        render() {
            return (
                <Col onClick={() => this.handleClick(this.props.result)}>{this.props.result.text}</Col>
            );
        }
    }
    

    …but this should not really be necessary.



  • Hi @JesperWe
    If you use classes the functions are not bind. There are a couple of options on what you can do, the first option binding the function to the class in the constructor. This is necessary for classes:

    export class Result extends Component {
      constructor(props) {
        super(props);
        this. handleClick = this. handleClick.bind(this);
      }
    
      handleClick() {
       ons.notification.alert( this.props.result._id );
      }
    
     render() {
         return (  <Col onClick={this.handleClick}>{this.props.result.text}</Col> );
        }
    }
    

    The second option is to use React.createClass, this bind it automatically:

    const Result = React.createClass({
     handleClick: function() {
       ons.notification.alert( this.props.result._id );
     },
     render: function() {
       return (
          <Col 
            onClick={this.handleClick}
          >{this.props.result.text}
          </Col>
       );
     }
    }
    export Result
    


  • Thanks Patrick, that makes sense now.


Log in to reply