How To Pass Events Between Components

October 2nd, 2015
Updated: January 27th, 2018

Imagine you have a component with a render() method like this:

render() {
  return (
    <div>
      <A/>
      <B/>
    </div>
  );
}

If <A/> has an <input> inside of it, and you want to capture any changes to that input, how would you do it? Turns out it's really easy. The render() method that does it looks like this:

render() {
  return (
    <div onChange={this.handleChange.bind(this)}>
      <A/>
      <B text={this.state.inputValue}/>
    </div>
  );
}

There are a few things missing from this component, of course. But just take a look at the render() method. The <div> has an onChange handler. This will capture the onChange event not just for that <div> but for all of its children.

Why do we put onChange on the <div> and not on <A/>? Putting onChange on a component won't do anything unless you handle it explicitly. Putting onChange on an HTML element will listen for that standard DOM event.

Interested in events other than onChange? Read the React Event System docs.

Full Example

The example is running here. Type anything into the <input> (component A) and see that it shows up in the space below (component B).

Here's the code, in 3 small files:

A.js

import React from "react";

// Component A has an <input> and that is all. No need to add an event handler,
// the events will 'bubble up'.
class A extends React.Component {
  render() {
    return <input placeholder="Type Something..." />;
  }
}
export default A;

B.js

import React from "react";
import PropTypes from "prop-types";

// Component B displays the value it is given.
class B extends React.Component {
  render() {
    return <p>{this.props.text}</p>;
  }
}
B.propTypes = {
  text: PropTypes.string
};
B.defaultProps = {
  text: null
};
export default B;

Main.js

import React from "react";

import A from "./A";
import B from "./B";

// The Main component listens for input changes in all of its children and
// passes the input value to 'B'.
class Main extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      inputValue: ""
    };
  }

  handleChange = event => {
    this.setState({
      inputValue: event.target.value
    });
  };

  render() {
    return (
      <div onChange={this.handleChange}>
        <A />
        <B text={this.state.inputValue} />
      </div>
    );
  }
}
export default Main;

Conclusion

Hopefully that helped you understand passing events between components in React. If not, let me know!