When you’re building innovative UIs for your game-changing apps, sometimes you’ll want to provide users with a more advanced WYSIWYG content creation experience. This can be achieved by adding a React rich text editor to your project, and it’s really easy to do!
In a previous post, we demonstrated how to get started with TinyMCE in a simple React app. In this article, we’ll go one step further and demonstrate how to enhance your React forms with the TinyMCE rich text editor in a controlled component.
Start with a simple React form as a controlled component
First, create a new React project using Create React App. Then open the src/App.js
file and replace the code with:
import React from "react";
class App extends React.Component {
constructor(props) {
super(props);
this.state = { content: "" };
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({ content: event.target.value });
}
handleSubmit(event) {
alert("Text was submitted: " + this.state.content);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<h2>Introduction to Software Engineering</h2>
<h3>Provide a course overview</h3>
<textarea
rows="20"
cols="80"
value={this.state.content}
onChange={this.handleChange}
/>
<br />
<input type="submit" value="Submit" />
</form>
);
}
}
export default App;
This component makes use of a state variable content
(initially ''
) to set and keep track of the textarea
value. The textarea
value is set initially with value={this.state.content}
. Then, every time textarea
changes, the handleChange()
function uses setState()
to update content
with the new value.
This means value
is always updated to reflect the current value of textarea
. When you’re ready to do something with the content entered, for example, when a save or submit button is pressed, you can access the current value directly from the component’s state. This is demonstrated in the handleSubmit()
function which is called, in this example, when the form is submitted.
Test it
Run npm run start
within the project directory. Once compiled, you'll be presented with a URL. Open the URL in a browser and you’ll have a simple React form running as a controlled component. (We’ve added some custom CSS because we like blue buttons 🔵😜)
Try typing some text and clicking Submit.

Add a rich text editor to your React form
Install the tinymce-react
component with your package manager of choice; for example, if using npm:
$ npm install @tinymce/tinymce-react
Continuing with the same project as before, open the src/App.js
file and import the Editor
component by adding it to the list of imports.
import React from "react";
import { Editor } from "@tinymce/tinymce-react";
In the same file, remove the textarea
from the form, replacing it with an Editor
component:
<form onSubmit={this.handleSubmit}>
<h2>Introduction to Software Engineering</h2>
<h3>Provide a course overview</h3>
<Editor
value={this.state.content}
init={{
height: 500,
menubar: false
}}
onEditorChange={this.handleChange}
/>
<br />
<input type="submit" value="Submit" />
</form>
The value
property is used to set the initial content. In this case, we’re basing it on the current value of content
(initially ''
).
The init
property is used to configure the editor. TinyMCE is extremely flexible in terms of how it can be configured – it can be used for a large number of applications. We’ve kept it simple for now – we’ve set the height and removed the menu bar.
The onEditorChange
property is used to handle the event, which will also require a change to the props accepted by the handleChange()
function:
handleChange(content, editor) {
this.setState({content});
}
Once you’ve saved these changes, you’ll have a rich text editor in your React form.
Note: A warning message may be displayed about registering your domain with Tiny Cloud. Dismiss this for now and try it out. We’ll talk about registration in the next section.

Register your domain with Tiny Cloud
Once you’ve got it running, you’ll need to register your domain to remove the warning message.
- Get a free API key (you’ll also get a 14-day trial of all our premium plugins).
- Add your domain to the list of Approved Domains in your Tiny account (
localhost
is included by default). - Add your API key to the editor config in
src/App.js
as shown below (replacingmy-api-key
with the API key displayed on your Tiny Dashboard).
<Editor
apiKey="my-api-key"
value={this.state.content}
init={{
height: 500,
menubar: false
}}
onEditorChange={this.handleChange}
/>
Note: The warning message might not disappear instantly – there may be a delay while your domain propagates through our system.
See the full example on CodeSandbox
More information
Refer to our comprehensive documentation for more information on integrating TinyMCE with React, including properties accepted by the editor component as well as event binding.
It’s time to customize the editor

Now that you’ve got the default rich text editor running in your React form, you’ll want to think more about how it’s configured, for example, which options make sense for your users and specific application?
- Do you need only a few options like bold, italics and underline.
- Do you want the full range of text editing options?
- Do you want the toolbar to be at the top or the bottom of the frame?
Furthermore, do you want to customize the skin to better fit with your design system?
Check out our related blog posts:
- A toolbar for all occasions: Customizing the TinyMCE toolbar
- Give me some skin: TinyMCE skins and icons
- A guide on what is rich text editor and how RTE differs from a simple text editor
- A comparison of best rich text editors for React