Handling Events on Stateless React Components

Doaa Mahely - Aug 16 '20 - - Dev Community

I decided to write up this post because whenever I start a new React project, I find myself googling the same question. So, how to handle events on a stateless (or dumb) React component?

Let's say we want to build a Markdown previewer in React. The components we'll need are:

  1. <EditingBox />, to write our Markdown in
  2. <PreviewBox />, to see the Markdown we typed rendered

Logically, these are the only two components we need. But where will we put the state? Both <EditingBox /> and <PreviewBox /> are hierarchically on the same level, so we can create a parent component to render them and contain the state. This is called lifting the state up. Let's call that component <App />.

Note: the below code uses the Marked.js library.

const EditingBox = (props) => {
    return <textarea>{props.input}</textarea>;
}

const PreviewBox = (props) => {
    return <div dangerouslySetInnerHTML={{__html: marked(props.input)}}></div>;
}

class App extends React.Component {
    state = {
      input: `# Welcome to my React Markdown Previewer!`
    };

  render() {
    return (
      <div class="container">
        <EditingBox {...this.state} />
        <PreviewBox {...this.state} />
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("app"));

Enter fullscreen mode Exit fullscreen mode

As we said, the <App /> component houses the state and renders the other two components. Now, we need a function that listens for change in the <EditingBox /> component and updates the state so that <PreviewBox /> can then get the updated state and display it.

This function will live in the <App /> component, because the state and all the functions that update it must live in the same component. It can be declared as follows:

  handleChange(event) {
    this.setState({
      input: event.target.value
    });
  }
Enter fullscreen mode Exit fullscreen mode

Now, we can pass down this method to <EditingBox />

  render() {
    return (
      <div class="container">
        <EditingBox {...this.state} onChange={() => this.handleChange(event)} />
        <PreviewBox {...this.state} />
      </div>
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

so that it can be used inside <EditingBox /> as a regular prop

const EditingBox = (props) => {
    return <textarea onChange={() => props.onChange()}>{props.input}</textarea>;
}

Enter fullscreen mode Exit fullscreen mode

Here is the full application

Thank you for reading. Until next time 👋
Cover photo by me.

. . . . . . . . . . . . . . . . . . . .
Terabox Video Player