Event in React
  • onClick={activateLasers}, instead of onclick="activateLasers()" in HTML
  • cannot return false to prevent default behavior in React, must call preventDefault explicitly
  • not need to call addEventListener to add listeners to a DOM element after it is created, instead, just provide a listener when the element is initially rendered
  • Use Event in React

    //index.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>Document</title>
    </head>
    <body>
    	<div id = "root"></div>
    	<script src="https://fb.me/react-0.14.3.js"></script>
    	<script src="https://fb.me/react-dom-0.14.3.js"></script>
    	<script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
    	<script src="script.js" type = "text/babel"></script>
    </body>
    </html>
    		
    var Product = React.createClass({
    	buy: function(){
    		alert("Buy ...");
    	},
    	render: function(){
    		return (
    			<div> // add into div, only can return one element
    				<p>Android</p>
    				<button onClick={this.buy}>Buy</button>
    			</div>
    		);
    	}
    });
    
    ReactDOM.render(<Product />, document.getElementById("root"));
    		
    Why Need Bind Function
    var module = {
      x: 42,
      getX: function() {
        return this.x;
      }
    }
    
    console.log(module.getX()); //this refer to module
    
    var unboundGetX = module.getX;
    console.log(unboundGetX()); // The function gets invoked at the global scope, this refers to window object or undefined in the strict mode
    // expected output: undefined
    
    //explicit hard binding
    var boundGetX = unboundGetX.bind(module); //bind function to module object
    console.log(boundGetX());
    // expected output: 42
    		
    Bind Function in React
  • class methods are not bound by default
  • If you forget to bind this.handleClick and pass it to onClick, this will be undefined when the function is actually called
  • class Toggle extends React.Component {
      constructor(props) {
        super(props);
        this.state = {isToggleOn: true};
    
        // This binding is necessary to make `this` work in the callback
        this.handleClick = this.handleClick.bind(this);
      }
    
      handleClick() {
        this.setState(state => ({
          isToggleOn: !state.isToggleOn
        }));
      }
    
      render() {
        return (
          <button onClick={this.handleClick}>
            {this.state.isToggleOn ? 'ON' : 'OFF'}
          </button>
        );
      }
    }
    
    ReactDOM.render(
      <Toggle />,
      document.getElementById('root')
    );
    		
    Avoid Bind
  • using the experimental public class fields syntax
  • This syntax is enabled by default in Create React App
  • class LoggingButton extends React.Component {
      // This syntax ensures `this` is bound within handleClick.
      // Warning: this is *experimental* syntax.
      handleClick = () => {
        console.log('this is:', this);
      }
    
      render() {
        return (
          <button onClick={this.handleClick}>
            Click me
          </button>
        );
      }
    }
    
    ReactDOM.render(
      <LoggingButton />,
      document.getElementById('root')
    );
    		
  • use an arrow function in the callback
  • class LoggingButton extends React.Component {
      handleClick() {
        console.log('this is:', this);
      }
    
      render() {
        // This syntax ensures `this` is bound within handleClick
        return (
          <button onClick={(e) => this.handleClick(e)}>
            Click me
          </button>
        );
      }
    }
    
    ReactDOM.render(
      <LoggingButton />,
      document.getElementById('root')
    );
    		
    Reference
  • This is why we need to bind event handlers in Class Components in React