Notice: The Monaca & Onsen UI Community Forum is shutting down.

For Onsen UI bug reports, feature requests and questions, please use the Onsen UI GitHub issues page. For help with Monaca, please contact Monaca Support Team.

Thank you to all our community for your contributions to the forum. We look forward to hearing from you in the new communication channels.

[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.