React State and Event Handling

React State

  • State is similar to props, but it is private and fully controlled by the component.
  • State object is initialized in the constructor
  • State object can be referred anywhere in the component by using the this.state.propsname eg., this.state.name, this.state.duration
  • To change the value in the state object, use the this.setState() method. When the value in the state object changes, the component will re-render
class Course extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: "Python",
      duration: 30,
      fee: 350,
      trainer: "Girish"
    };
  }
 changeCourse = (event) => {
    this.setState({name: event.target.value});
  }
 changeTrainer = () => {
    this.setState({trainer:"Krishna"});
  }
  render() {
    return (
      <div>
        <h1>Course Name: {this.state.name}</h1>
        <p>
          Course Duration: {this.state.duration} <br/>
          Course Fee: {this.state.fee} <br/>
          Course Trainer: {this.state.trainer} <br/>
        </p>
        Course Name: <input type="text" onChange={this.changeCourse}/>  <br/>
        <button onClick={this.changeTrainer}>Change Trainer</button>  <br/>

      </div>

    );
  }
}
ReactDOM.render(<Course />, document.getElementById('root'));

Do Not Modify State directly, Instead, use setState(). Bellow is the sample background color change example using setState() while toggling the button. In JavaScript, 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 ToggleColor extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};
    this.state.color = "";
    // This binding is necessary to make `this` work in the callback
    this.handleClick = this.handleClick.bind(this);   
  }
  handleClick() {
    this.setState(state => ({
      isToggleOn: !state.isToggleOn
    }));
   // console.log(this.state.isToggleOn);
    if(!this.state.isToggleOn)
    {
      this.setState({color : "blue"})
    }
    else
    {
      this.setState({color : "yellow"})

    }
  }   
  render() {
   var myStyle = {
     backgroundColor: this.state.color}
    
   return (
      <div>
            <h1 style= {myStyle}>background color </h1>      

            <button onClick={this.handleClick}> {this.state.isToggleOn ? 'yellow' : 'blue'}
            </button> 
      </div>
    );
  }
}
ReactDOM.render(
  <ToggleColor />,
  document.getElementById('root')

);

React Events

  • React events are named using camelCase, rather than lowercase. eg handleClick()
  • With JSX you pass a function as the event handler, rather than a string. eg onClick={display}
  • In JavaScript, class methods are not bound by default. For class methods in React, this keyword should represent the component that owns the method. Using arrow functions, this will always represent the object that defined the arrow function.

With Normal display() method inside Course Class Component

class Course extends React.Component {
  constructor(props) {
    super(props)
   }
  display() {
    alert(this);
  }
  render() {
    return (
      <button onClick={this.display}>Display Alert</button>
    );
  }
}
ReactDOM.render(<Course />, document.getElementById('root'))

With arrow function display inside Course Class Component

class Course extends React.Component {
  constructor(props) {
    super(props)
    
  }
  display= () => {
    alert(this);
  }
  render() {
    return (
      <button onClick={this.display}>Display Alert</button>
    );
  }
}

ReactDOM.render(<Course />, document.getElementById('root'))
  • If you have to use regular javascript functions instead of arrow functions then you have to bind this to the component instance using the bind() method
class Course extends React.Component {
  constructor(props) {
    super(props)
    this.display = this.display.bind(this)
   }
  display() {
    alert(this);
  }
  render() {
    return (
      <button onClick={this.display}>Display Alert</button>
    );
  }
}
ReactDOM.render(<Course />, document.getElementById('root'))

Passing Arguments to Event Handlers

  • Create anonymous arrow function and call the function with arguments in the callback
class Course extends React.Component {
  constructor(props) {
    super(props)
   }
  display(data) {
    alert("Value: "+ data);
  }
  render() {
    return (
      <button onClick={()=>this.display("React")}>Display Alert</button>
    );
  }
}
ReactDOM.render(<Course />, document.getElementById('root'))
  • Bind the event handler display() to this.
class Course extends React.Component {
  constructor(props) {
    super(props)
   }
  display(data) {
    alert("Value: "+ data);
  }
  render() {
    return (
      <button onClick={this.display.bind(this, "React")}>Display Alert</button>
    );
  }
}
ReactDOM.render(<Course />, document.getElementById('root'))

With an arrow function, we have to pass the event object manually. The “e” argument representing the React event will be passed as a second argument after the first argument.

class Course extends React.Component {
  constructor(props) {
    super(props)
   }
   printValue(value, event) {
    alert("Value: " + value + "  " + "\n" + "Event Type: " + event.type);
  }
  render() {
    return (   // This syntax ensures 'this' is bound within printValue
      <button onClick={(e) => this.printValue("React JS", e)}>Submit</button>
      );
  }
}
ReactDOM.render(<Course />, document.getElementById('root'))

With bind any further arguments are automatically forwarded

class Course extends React.Component {
  constructor(props) {
    super(props)
   }
   printValue(value, event) {
    alert("Value: " + value + "  " + "\n" + "Event Type: " + event.type);
  }
  render() {
    return (
      <button onClick={this.printValue.bind(this, "React")}>Print Value with Bind</button>
      );
  }
}
ReactDOM.render(<Course />, document.getElementById('root'))

References

  • https://reactjs.org/docs/state-and-lifecycle.html
  • https://reactjs.org/docs/handling-events.html
  • https://reactjs.org/docs/conditional-rendering.html

Learn More about React features in the next upcoming blog articles

Happy Learning!