DEV Community

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

Posted on

3 2

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.

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more →

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!

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more