WYSIWYG editing in React with Draft.js
Tags: webdev, javascript, draftjs
Published: 2023-02-09 00:45:45

by [Ejiro Thankgod](https://blog.openreplay.com/authors/ejiro-thankgod)

For capturing short text segments, like a login, address, or city, developers often utilize plaintext inputs or `textarea` components. In certain circumstances, users must be able to submit stylish, formatted text along with multimedia components in web applications. However, plaintext inputs cannot meet these needs; thus, developers typically employ the idea of rich text editors.

When it comes to content creation, rich text editors have become a crucial part of how we interact with web apps. WYSIWYG HTML editors, which provide a live preview of the styled and formatted text segments, are the most common type of web-based rich text editors. Rich text editors offer a powerful solution for content creators to develop and publish HTML everywhere while allowing you to manage the text's appearance.


## Intro to [Draft.js](https://draftjs.org/)

Immutable-js is used to build the [Draft.js](https://draftjs.org/) paradigm, which offers an API with functional state changes and heavily relies on data persistence for scalable memory consumption. It was introduced as a rich text editor tool for React at the React.js Conference 2016.

[Draft.js](https://draftjs.org/) offers rich text editor APIs for programmers to create their very own text editor. To create and exhibit rich text, it provides a pre-built React component. By providing a declarative API that supports capabilities ranging from basic text formatting to embedding media elements such as hyperlinks, photos, mentions, and more, whether you want to support a few inline text styles or develop a sophisticated text editor for long-form articles, Draft.js enables you to design any sort of rich text input.

## React-Draft-Wysiwyg

React and the Draft.js libraries were used to create the `react-draft-wysiwyg` library, a WYSIWYG (What You See Is What You Get) editor. It has a ton of customizable built-in features, including text styling buttons, keyboard shortcut support, the ability to embed media files, support for emojis, and more that you would expect from a contemporary HTML editor component.

## Features of React-Draft-Wysiwyg

The `react-draft-wysiwyg` library offers a rich text editor component with all the general WYSIWYG features listed below.


- Support for inline styles: Bold, Italic, Underline, StrikeThrough, Code, Subscript, and Superscript.
- Option to change the order of the controls in the toolbar.
- Support for block types: Paragraph, H1 - H6, Blockquote, Code.
- Option to change styles and icons in the toolbar.
- Option to show toolbar only when the editor is focused.
- Option to add custom controls to the toolbar.
- Support for text-alignment.
- Support for setting font-size and font-family.
- Support for ordered/unordered lists and indenting.
- Configurable toolbar with the option to add/remove controls.


## Advantages of React-Draft-Wysiwyg

- **Simple setup and integration options**: The `react-draft-wysiwyg` library has a straightforward API, self-explanatory component props, and well-written documentation. This makes setting up a rich text editor for your React project quick and easy. Additionally, the rich text editor component supports both specific well-known Draft.js community libraries and core APIs.

- **Flexibility and ability to customize**: As well as providing a flexible feature set, this library does not restrict the feature scopes of developers. Through a variety of component props, it enables developers to personalize the toolbar and functionalities. Even adding custom toolbar elements is simple!


## Getting started with React-Draft-Wysiwyg.

Let's start by creating a new project in the directory of your choice. To start your project, type any of the commands in the list below in the command line.

```
    npx create-react-app text-editor-example
    --or--
    yarn create react-app text-editor-example
    --or--
    pnpm create react-app text-editor-example
```

Once created, run it by going to the project folder's root and typing the command below:
```
    npm start
    --or--
    yarn start
    --or--
    pnpm start
```

The commands shown below will add the `react-draft-wysiwyg` and `draft.js` packages to your React project:

```
    npm install --save react-draft-wysiwyg draft-js
```

## Preparing the Editor

We'll need to make some changes to the `src/App.js` file before we can start. We will import `EditorState` from `draft-js` along with the `editor` component and styles from `react-draft-wysiwyg`.

Add some code to make a rich text editor visible. Your App.js file should now include the following code:
```javascript
    import React, { useState } from 'react';
    import { EditorState } from 'draft-js';
    import { Editor } from 'react-draft-wysiwyg';
    import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css';
    import './App.css';
    function App() {
      const [editorState, setEditorState] = useState(
        () => EditorState.createEmpty(),
      );
      return (
        <div className="App">
          <h1>Text Editor</h1>
          <Editor
            editorState={editorState}
            onEditorStateChange={setEditorState}
            placeholder="The message goes here..."
          />
        </div>
      )
    }
    export default App;
```

The `createEmpty` function of `EditorState` will create an empty state as our starting point. `EditorState` is used by the `editor` as a prop. The view doesn't look fantastic after storing the modifications and updates, as you will see:


![1](https://blog.openreplay.com/images/wysiwyg-editing-in-react-with-draft-js/images/image01.png)




<h2>Session Replay for Developers</h2> 
<p><em>
Uncover frustrations, understand bugs and fix slowdowns like never before with <strong><a href="https://github.com/openreplay/openreplay" target="_blank">OpenReplay</a></strong> — an open-source session replay suite for developers. It can be <strong>self-hosted</strong> in minutes, giving you complete control over your customer data
</em></p>
<img alt="OpenReplay" width="768" height="400" src="https://blog.openreplay.com/assets/overview_Z17Qdyg.png" class="astro-UXNKDZ4E" loading="lazy" decoding="async">
<em>Happy debugging! <a href="https://openreplay.com" target="_blank">Try using OpenReplay today.</a></em>






## Editor styling

In editor styling, style props can help the editor's various sections stand out more clearly. The class used for a certain area or an object with the styles can be the props:

- toolbarClassName=”toolbarClassName”
- wrapperClassName=”wrapperClassName”
- editorClassName=”editorClassName”

To style the editor, add the following `className` properties to the `Editor` component and the appropriate styles to `App.css`:

```javascript
    <Editor
      editorState={editorState}
      toolbarClassName="toolbarClassName"
      wrapperClassName="wrapperClassName"
      editorClassName="editorClassName"
      onEditorStateChange={this.onEditorStateChange}
    />;

    .toolbarClassName {
      border-radius: 10px;
    }
    .wrapperClassName {
      border: 1px solid rgb(231, 221, 221);
      padding: 1rem;
    }
    .editorClassName {
      background-color:rgb(239, 222, 222);
      border-radius: 10px;  
      padding: 1rem; 
    }
```

Now, the rich text editor should resemble the following:

![2](https://blog.openreplay.com/images/wysiwyg-editing-in-react-with-draft-js/images/image02.gif)


N/B: In the development mode, you can see a warning that reads, "Can't call `setState` on a component." React displays this warning message due to a problem with `react-draft-wysiwyg`. Hopefully, library administrators will patch this problem as soon as possible. You may temporarily turn off React Strict Mode for this lesson by doing the following:
```javascript
    import ReactDOM from 'react-dom/client';
    import './index.css';
    import App from './App';
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
      // <React.StrictMode>
        <App />
      // </React.StrictMode>
    );
```

## EditorState Props

An uncontrolled or regulated component can both exist in the editor. `EditorState`, the editor's top-level state object, is used to create a controlled editor. While a flow type that indicates the anticipated structure of the raw format of the contents can be used to create an uncontrolled editor, such as `EditorState` or `RawDraftContentState`. The following props will be passed to the controlled editor if we want to construct one:

- `editorState`: A prop to manage updating the editor's state 
- `onEditorStateChange`: a function that receives an object parameter of type `EditorState` and is called whenever the editor state changes

These will be added to our `editor` component, and it will then appear as follows:
```javascript
    <Editor
      editorState={editorState}
      onEditorStateChange={setEditorState}
      toolbarClassName="toolbarClassName"
      wrapperClassName="wrapperClassName"
      editorClassName="editorClassName"
    />
```
By passing `initialEditorState`, `EditorState` can also be used to create an uncontrolled editor. Once the editor state has been constructed, initialize it with this object of type `EditorState`:

```javascript
    <Editor
      initialEditorState={editorState}
      onEditorStateChange={setEditorState}
      toolbarClassName="toolbarClassName"
      wrapperClassName="wrapperClassName"
      editorClassName="editorClassName"
      placeholder="The message goes here..."
    />
```
The use of `RawDraftContentState` is the alternative method for achieving an uncontrolled editor. The unchecked editor accepts the following props: `initialEditorState` and `onContentStateChange`.

```javascript
    <Editor
      initialContentState={contentState}
      onContentStateChange={this.onContentStateChange}
      toolbarClassName="toolbarClassName"
      wrapperClassName="wrapperClassName"
      editorClassName="editorClassName"
    />
```

Using `RawDraftContentState` to achieve editor-controlled behavior is not advised. Performance is affected when `contentState` is converted to an instance of `editorState`.

## Conclusion

This post focused on building a rich text editor with a toolbar that already has a number of options for entering and displaying text. You can add features that allow you to store the text in a database, retrieve it, and make changes to it if you want to push yourself even further.



[![newsletter](https://blog.openreplay.com/newsletter_Z1P0UIP.png)](https://newsletter.openreplay.com/)