Typing effect component in react

Learn how to create typing effect in react.

Typing effect is way of showing text to the users as if some one is typing it.

Typing effect in react

We will create a component in react which will show the typing effect for the text that has been passed.

For our development we will need some external packages.

  • prop-types: To validate the props we will receive.
  • classnames: With these we can use CSS classes as javascript objects, we just need to name our CSS file as filename.module.css

Let us start the development by importing all the required packages at the top.

import React, { Component } from "react";
import PropTypes from "prop-types";
import styles from "./index.module.css";

class TypingEffect extends Component {
  //Other code will go here
}

export default TypingEffect;

Validate the props so that we get an idea of what are things we are expecting and also set the default ones in case required props are missing.

static propTypes = {
    text: PropTypes.string.isRequired,
    wordsPerSecond: PropTypes.number.isRequired
  };

  static defaultProps = {
    text:
      "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
    wordsPerSecond: 20
  };

Basically the two most important thing we will need are.
1. The text that will be shown as being typed.
2. Speed at which typing will take place.

You can extend the component and add other things as per requirement.

As you can see we have created a stateful component because we need to maintain the state. So create the state to store the data.

state = {
  runningText: "",
  index: 0
};

The two things we are tracking in the state are

  • runningText: The amount of text that has been typed.
  • index: To keep track of things typed and add the new characters to the runningText.

lets create the function to update the state with the runningText and index.

generateText = () => {
    //Clear existing time if running
    clearTimeout(this.timer);

    const { runningText, index } = this.state;
    const { text, wordsPerSecond } = this.props;

    //Speed of generting text
    const speed = 1000 / wordsPerSecond;

    if (index < text.length) {
      this.timer = setTimeout(() => {
        this.setState({
          runningText: runningText + text[index],
          index: index + 1
        });
      }, speed);
    } else {
      //Clear timer if generated completely
      clearTimeout(this.timer);
    }
  };

Our function basically keeps adding the words from the original text to the runningText at the given interval by accessing the words with the given index.

String characters can be accessed just like an array in javascript.

With each call the index increases. So we check if index has increased the original text length or not and if yes that means we have typed everything so stop the timer.

We are clearing the timer initially because we don’t to run more than 1 timer at a time.

It is important to call this function at appropriate lifecycle methods.

  componentDidMount() {
    this.generateText();
  }

  componentDidUpdate() {
    this.generateText();
  }

Start the typing effect as soon as component is mounted and also when the component is updated.

componentDidMount is fired only once, but componentDidUpdate is fired every time the component is updated.

So our typing function is called every time runningText is changed, that is why we are clearing the old timer and starting the new.

Create the layout to display the text. The layout is composed of two parts.

First, the text and second the blinking cursor.

 render() {
    const { runningText } = this.state;

    return (
      <div className={styles.typingArea}>
        {runningText}
        <span className={styles.blinkingCursor}></span>
      </div>
    );
  }

In the last, clear the timer when component is being removed.

  componentWillUnmount() {
    clearTimeout(this.timer);
  }

Complete code of typing effect component in react.

import React, { Component } from "react";
import PropTypes from "prop-types";
import styles from "./index.module.css";

class TypingEffect extends Component {
  static propTypes = {
    text: PropTypes.string.isRequired,
    wordsPerSecond: PropTypes.number.isRequired
  };

  static defaultProps = {
    text:
      "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
    wordsPerSecond: 20
  };

  state = {
    runningText: "",
    index: 0
  };

  componentDidMount() {
    this.generateText();
  }

  componentDidUpdate() {
    this.generateText();
  }

  generateText = () => {
    //Clear existing time if running
    clearTimeout(this.timer);

    const { runningText, index } = this.state;
    const { text, wordsPerSecond } = this.props;

    //Speed of generting text
    const speed = 1000 / wordsPerSecond;

    if (index < text.length) {
      this.timer = setTimeout(() => {
        this.setState({
          runningText: runningText + text[index],
          index: index + 1
        });
      }, speed);
    } else {
      //Clear timer if generated completely
      clearTimeout(this.timer);
    }
  };

  componentWillUnmount() {
    clearTimeout(this.timer);
  }

  render() {
    const { runningText } = this.state;

    return (
      <div className={styles.typingArea}>
        {runningText}
        <span className={styles.blinkingCursor}></span>
      </div>
    );
  }
}

export default TypingEffect;

Complete style code of typing effect in react

We need to show the blink effect on the cursor to give the feel of text being actually typed.

.typingArea {
  padding: 20px 25px;
  margin: 0 0 20px;
  color: #445d6e;
  font-size: 18px;
  background-color: #fff;
  box-shadow: 0 2px 4px rgba(50, 50, 93, 0.7);
  white-space: pre-wrap;
  border-radius: 4px;
  line-height: 1.9em;
  flex: 0 0 90%;
  width: 90%;
}

.blinkingCursor {
  width: 2px;
  height: 1em;
  background: #607d8b;
  display: inline-block;
  margin: 0 1px;
  animation: blink 0.9s infinite;
}

@keyframes blink {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

Input

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import TypingEffect from "./Components/TypingEffect";
import * as serviceWorker from "./serviceWorker";

ReactDOM.render(
  <div className="abc">
    <TypingEffect />
  </div>,
  document.getElementById("root")
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();