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:
-
<EditingBox />
, to write our Markdown in -
<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"));
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
});
}
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>
);
}
}
so that it can be used inside <EditingBox />
as a regular prop
const EditingBox = (props) => {
return <textarea onChange={() => props.onChange()}>{props.input}</textarea>;
}
Here is the full application
Thank you for reading. Until next time 👋
Cover photo by me.
Top comments (2)
You can also make the class component as function component, then use the
useState
hooks and pass it down alsoHi Pratik. I'm still learning React and haven't gone through hooks yet, so I'll keep that in mind. Thank you!