DEV Community

Mint
Mint

Posted on

How to use react-native-rich-editor on React Native

This article will show you an example of how to implement a react-native-rich-editor and its common problems. In this example, I'm working on Expo (in case you wonder if this library supported Expo or not ).

The most common problems

  • How to check for empty content
  • How to hide keyboard or dismiss the keyboard
  • Crashed on Android when using navigation

I will show you the solutions to these problems in this example.

Setup

Install react-native-pell-rich-editor alongside react-native-webview.



yarn add react-native-pell-rich-editor
or
npm i react-native-pell-rich-editor


Enter fullscreen mode Exit fullscreen mode

Example

On react-native-pell-rich-editor, they have two components which are the RichEditor and RichToolbar.

RichEditor

To receive a fully functional Rich text Editor, add this component in your view hierarchy.



 <RichEditor
   ref={richText} // from useRef()
   onChange={richTextHandle}
   placeholder="Write your cool content here :)"
   androidHardwareAccelerationDisabled={true}
   style={styles.richTextEditorStyle}
   initialHeight={250}
 />


Enter fullscreen mode Exit fullscreen mode

If your app on Android crashed when you navigated to another screen make sure that you use

androidHardwareAccelerationDisabled={true}

This is what it looks like:

RichEditor

RichToolbar

This is a Component that provides a toolbar. It is designed to be used together with a RichEditor component.



<RichToolbar
   editor={richText}
   selectedIconTint="#873c1e"
   iconTint="#312921"
   actions={[
     actions.insertImage,
     actions.setBold,
     actions.setItalic,
     actions.insertBulletsList,
     actions.insertOrderedList,
     actions.insertLink,
     actions.setStrikethrough,
     actions.setUnderline,
   ]}
   style={styles.richTextToolbarStyle}
/>


Enter fullscreen mode Exit fullscreen mode

Because RichToolbar component needs to ref to RichEditor component I recommend you to write RichEditor component above RichToolbar component and then you can style them by using flexDirection: "column-reverse" I will show you how to style them in the complete code

How to check for empty content

You might want to check for empty content before users submit their information, or what should we do if they only type whitespaces?

We will update 2 states in richTextHandle function, for showing them the error text and we will need the HTML content that we get from richEditor to check for empty content later.

richTextHandle function:



  const richTextHandle = (descriptionText) => {
    if (descriptionText) {
      setShowDescError(false);
      setDescHTML(descriptionText);
    } else {
      setShowDescError(true);
      setDescHTML("");
    }
  };


Enter fullscreen mode Exit fullscreen mode

We will replace HTML tags and whitespaces with the empty string and now we have only texts without any HTML tag so we can check if the length of the text is less than or equal to zero.

submitContentHandle function:



 const submitContentHandle = () => {
    const replaceHTML = descHTML.replace(/<(.|\n)*?>/g, "").trim();
    const replaceWhiteSpace = replaceHTML.replace(/&nbsp;/g, "").trim();

    if (replaceWhiteSpace.length <= 0) {
      setShowDescError(true);
    } else {
      // send data to your server!
    }
  };


Enter fullscreen mode Exit fullscreen mode

This is what it looks like when users submit an empty content:

Empty Content

How to hide keyboard or dismiss the keyboard

Keyboard

Because RichEditor is not general input you can't just press outside input to dismiss the keyboard. You need to write a function to dismiss the keyboard by yourself. In this case, I will write that function outside the RichText like this:



<Pressable onPress={() => richText.current?.dismissKeyboard()}>
 <Text style={styles.headerStyle}>Your awesome Content</Text>
   <View style={styles.htmlBoxStyle}>
     <Text>{descHTML}</Text>
   </View>
</Pressable>


Enter fullscreen mode Exit fullscreen mode

The Complete Code

Here is the complete code on Github: link



import { useRef, useState } from "react";
import {
  Pressable,
  SafeAreaView,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from "react-native";
import {
  actions,
  RichEditor,
  RichToolbar,
} from "react-native-pell-rich-editor";

export default function App() {
  const richText = useRef();

  const [descHTML, setDescHTML] = useState("");
  const [showDescError, setShowDescError] = useState(false);

  const richTextHandle = (descriptionText) => {
    if (descriptionText) {
      setShowDescError(false);
      setDescHTML(descriptionText);
    } else {
      setShowDescError(true);
      setDescHTML("");
    }
  };

  const submitContentHandle = () => {
    const replaceHTML = descHTML.replace(/<(.|\n)*?>/g, "").trim();
    const replaceWhiteSpace = replaceHTML.replace(/&nbsp;/g, "").trim();

    if (replaceWhiteSpace.length <= 0) {
      setShowDescError(true);
    } else {
      // send data to your server!
    }
  };

  return (
    <SafeAreaView edges={["bottom", "left", "right"]} style={{ flex: 1 }}>
      <View style={styles.container}>
        <Pressable onPress={() => richText.current?.dismissKeyboard()}>
          <Text style={styles.headerStyle}>Your awesome Content</Text>
          <View style={styles.htmlBoxStyle}>
            <Text>{descHTML}</Text>
          </View>
        </Pressable>
        <View style={styles.richTextContainer}>
          <RichEditor
            ref={richText}
            onChange={richTextHandle}
            placeholder="Write your cool content here :)"
            androidHardwareAccelerationDisabled={true}
            style={styles.richTextEditorStyle}
            initialHeight={250}
          />
          <RichToolbar
            editor={richText}
            selectedIconTint="#873c1e"
            iconTint="#312921"
            actions={[
              actions.insertImage,
              actions.setBold,
              actions.setItalic,
              actions.insertBulletsList,
              actions.insertOrderedList,
              actions.insertLink,
              actions.setStrikethrough,
              actions.setUnderline,
            ]}
            style={styles.richTextToolbarStyle}
          />
        </View>
        {showDescError && (
          <Text style={styles.errorTextStyle}>
            Your content shouldn't be empty 🤔
          </Text>
        )}

        <TouchableOpacity
          style={styles.saveButtonStyle}
          onPress={submitContentHandle}>
          <Text style={styles.textButtonStyle}>Save</Text>
        </TouchableOpacity>
      </View>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    height: "100%",
    backgroundColor: "#ccaf9b",
    padding: 20,
    alignItems: "center",
  },

  headerStyle: {
    fontSize: 20,
    fontWeight: "600",
    color: "#312921",
    marginBottom: 10,
  },

  htmlBoxStyle: {
    height: 200,
    width: 330,
    backgroundColor: "#fff",
    borderRadius: 10,
    padding: 20,
    marginBottom: 10,
  },

  richTextContainer: {
    display: "flex",
    flexDirection: "column-reverse",
    width: "100%",
    marginBottom: 10,
  },

  richTextEditorStyle: {
    borderBottomLeftRadius: 10,
    borderBottomRightRadius: 10,
    borderWidth: 1,
    borderColor: "#ccaf9b",
    shadowColor: "#000",
    shadowOffset: {
      width: 0,
      height: 2,
    },
    shadowOpacity: 0.23,
    shadowRadius: 2.62,
    elevation: 4,
    fontSize: 20,
  },

  richTextToolbarStyle: {
    backgroundColor: "#c6c3b3",
    borderColor: "#c6c3b3",
    borderTopLeftRadius: 10,
    borderTopRightRadius: 10,
    borderWidth: 1,
  },

  errorTextStyle: {
    color: "#FF0000",
    marginBottom: 10,
  },

  saveButtonStyle: {
    backgroundColor: "#c6c3b3",
    borderWidth: 1,
    borderColor: "#c6c3b3",
    borderRadius: 10,
    padding: 10,
    width: "25%",
    alignItems: "center",
    justifyContent: "center",
    shadowColor: "#000",
    shadowOffset: {
      width: 0,
      height: 2,
    },
    shadowOpacity: 0.23,
    shadowRadius: 2.62,
    elevation: 4,
    fontSize: 20,
  },

  textButtonStyle: {
    fontSize: 18,
    fontWeight: "600",
    color: "#312921",
  },
});



Enter fullscreen mode Exit fullscreen mode

Happy Coding! 👩🏻‍💻

Top comments (5)

Collapse
 
mohd_7991bf3857e2e98b2a0 profile image
Moh'd

When i run this code it showing this error:

Warning: Error: Exception in HostFunction: TypeError: expected dynamic type array', but had typestring'

help me to fix this

Collapse
 
manoj_sekar_0640beb7fa4c1 profile image
Manoj Sekar

Hi, I have a doubt, Im getting a response from API like HTML so can i able to load HTML format in Rich Editor ?

Collapse
 
hamza_butt_bee01239f4f28 profile image
Hamza Butt

Hello I have a problem like I want to show text what written in Rich editor as you are showing buts its in div tags ? How should I run away from it like I only want plain text to be shown as I write .

Collapse
 
abhinavjha27 profile image
ABHINAV JHA

You can use HtmlView to render it. It will then show as a plain text.

Collapse
 
tchaikovsky1114 profile image
Kim-Myungseong

thank you so much mint!