DEV Community

Cover image for Handling Events on Stateless React Components
Doaa Mahely
Doaa Mahely

Posted on

Handling Events on Stateless React Components

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.

Top comments (2)

Collapse
 
pthacker profile image
Pratik thacker

You can also make the class component as function component, then use the useState hooks and pass it down also

Collapse
 
dmahely profile image
Doaa Mahely

Hi Pratik. I'm still learning React and haven't gone through hooks yet, so I'll keep that in mind. Thank you!