A nice text streaming effect in React
Published on
Welcome!
In this article, we will be creating a text streaming effect using a React Hook. This effect is becoming increasingly popular, and can be used to elevate the user experience.
In essence it is about simulating what would be a conversation with a computer terminal 🤖. But it also allows to present content gradually while at the same time focusing the user's attention.
So let's get started!
Text Streaming Effect
The typing or text streaming effect is a fun way to animate text on your app or website. All this, without needing to open an actual SSE stream or use WebSockets 😅.
It also provides the benefit of being able to control the speed of the animation.
Full Text Streaming
Try out the streaming effect by adjusting the total duration
Interestingly enough using CSS to create this effect can be quite challenging.
In this article we are going the JavaScript route, by creating a React Hook that will allow you to easily implement this effect within any React component.
Letter Streaming
Try out the streaming effect by adjusting the duration per letter
This gives us the flexibility to control the duration of the animation, as well as the type of animation.
Full Text Streaming
Try out the streaming effect by adjusting the total duration
And as you can see, it can be done for any text content. By encapsulating the logic within a hook (a reusable function after all), you can easily add this effect to any component in your application.
Show me the Code
So let's take a look at the details behind this magic.
We will start with a simplified version of the React hook that streams the text letter by letter. Also allowing you to set how long it takes to print each new letter.
The Hook (Letter by Letter)
Technical Explanation
Okay, so let's break this down. We are combining a couple React hooks with the power of a setInterval function.
The useEffect
hook is responsible for updating the text state
every timeDelta
milliseconds. While useState
is used
to store the current text
.
timeDelta
is the time it takes to draw a new letter.
The text
state variable is initially set to an empty string. And on each
interval, we update text
by adding a new letter from the wholeText
property. Which contains the complete text that we want to "stream".
A very key point to note is that we clear the interval when the text is fully streamed. This is done by checking if the current text length is equal to the length of the whole text.
Additionally, we clear the interval when the component is unmounted. This
is done by returning a cleanup function from the useEffect
hook. This
is important to prevent memory leaks.
The useStreamedText
hook takes in an object with the following properties:
wholeText
: The text that you want to stream.duration
: The time it takes to draw a new letter.
And returns an array with the current text (although at this point we don't need an array, we will add more features to this hook later on).
Usage
This is how you would use the hook in a React component.
And that could be it! But where is the fun in that? Let's add some more features to this hook.
Adding Full Duration control
We are adding the ability to set the time it takes to paint the entire text.
This can be set by changing the new durationType
property to fullText
.
All that was needed besides the durationType
property was to calculate
the timeDelta
based on the durationType
. This is achieved by dividing
the duration over the length of the whole text.
To support both duration types, we had to use a ternary operator to
calculate the timeDelta
.
The reason we multiply the duration by 1000 is to convert it to milliseconds, the unit which the setInterval function is expecting.
Usage
This is how you would use the hook with the new durationType
property.
A final touch (adding a delay)
We will be adding a delay so that the animation doesn't start immediately. This can prove useful when staggering animations, specially when combined with durationType = 'fullText'.
This way you can set a delay for each text element, and they will start streaming at different times.
We added a new property delay
to the UseStreamProps
object. This
property is used to set the delay before the animation starts.
We also started tracking the elapsedTime
using the setElapsedTime
function.
This is used to check if the delay has passed.
Note that we will only update the text if the elapsed time is greater than the delay.
Check it out in action:
Full Text Streaming
Try out the streaming effect by adjusting the delay and total duration
Usage
And that's it! You now have a fully functional React hook that can be used to emulate text streaming on your application.