How to Create an Interactive Typing Effect in React with Skip Animation Feature
A developer's notes and tips on implementing a smooth, multi-paragraph typing effect in React with a skip animation feature. Covers state management...
Abstract:
This post shares a developer's notes and tips for implementing a smooth, multi-paragraph typing animation effect in React, complete with a feature to skip the animation. Key aspects covered include state management using React hooks (useState, useEffect, useCallback), alternatives to direct DOM manipulation, handling user events to skip typing, and managing internationalized text with react-i18next.
Estimated reading time: 3 minutes
(Notes for myself - you can check out the effect at 8bitoracle.ai)
Getting a typing effect to work properly can be quite challenging. I have a few paragraphs of text and wanted to create a typing effect for it, allowing the user to skip the animation. If a user presses a spacebar or clicks on a paragraph, the current paragraph should complete instantly, and the next one should begin typing.
A few tips:
-
Directly changing the page structure with DOM manipulation can often cause bugs. It is usually better to update HTML elements by changing their content or visibility through React's state.
-
It's simpler to create a typing effect by showing and hiding parts of the text, instead of actually typing out characters one by one or copying them from a hidden place.
Here are the main lessons from the code I used to create a typing effect in React. This effect works for several paragraphs and lets the user skip the animation at any time:
-
State Management:
- Use the
useStatehook to manage the state of the current paragraph's index (currentParagraphIndex) and the number of characters currently visible (visibleCharacters). - Update these state variables as needed to control the typing and keep track of its progress.
- Use the
-
Parsing Paragraphs:
- Get the paragraphs from the
backstorydata. Use the selected language to pick the right text, using JavaScript'sObject.entriesandmapmethods. - Make an array of paragraph items. Each item should have an
idandtextto make them easier to show and manage.
- Get the paragraphs from the
-
Typing Effect:
- Use the
useEffecthook to control the typing effect based on thevisibleCharactersandcurrentParagraphIndexstate variables. - Use a timer (
setTimeout) to slowly show more characters in the current paragraph. - After the current paragraph is fully typed, wait a moment and then start typing the next one.
- To prevent problems (memory leaks), clear the timer if the component is removed or if its dependencies change.
- Use the
-
Skipping Animation:
- Create a
skipTypingAnimationfunction. This lets the user skip the typing and see the whole current paragraph at once. - Use the
useCallbackhook to memoize this function (meaning React will reuse the same function instance if its dependencies haven't changed), which can help optimize performance.
- Create a
-
Event Handlers:
- Set up event handlers so that pressing a key (like spacebar) or touching/clicking the screen runs the
skipTypingAnimationfunction. - Use
useEffecthooks to add these event listeners when needed and remove them when not, based on certain conditions (dependencies).
- Set up event handlers so that pressing a key (like spacebar) or touching/clicking the screen runs the
-
Rendering:
- Go through the
paragraphsarray and show each paragraph as a separate<p>HTML element. - Figure out which parts of each paragraph to show or hide. Use the
currentParagraphIndexandvisibleCharactersstate values for this. - Show the visible text. For the current paragraph, also show a typing cursor. You can also include the hidden text but with a 'hidden' style so it's not seen until typed.
- Make each paragraph clickable or touchable to let users skip the animation for that paragraph.
- Go through the
-
CSS Styling:
- Use CSS classes to style the text, the cursor, and the hidden parts.
- Use CSS animations or transitions to make the typing cursor blink.
-
Performance Optimization:
- Use
useCallback(for functions) anduseMemo(for values) hooks to memoize parts of your component. This means React reuses them if their inputs haven't changed, preventing unnecessary recalculations and improving performance. - Make rendering faster by only updating the parts of the component that change when the state changes.
- Use
-
Internationalization:
- Use the
useTranslationhook from thereact-i18nextlibrary to support different languages (internationalization). - Get the correct text translations from the
backstorydata, based on the chosen language.
- Use the
By using these ideas, you can build a typing effect in React that works well, is interactive, and supports multiple languages.