Skip to content

Instantly share code, notes, and snippets.

@matthewoestreich
Created September 22, 2019 21:49
Show Gist options
  • Save matthewoestreich/4b78b6f0dfa1cb533999180c85d77ef7 to your computer and use it in GitHub Desktop.
Save matthewoestreich/4b78b6f0dfa1cb533999180c85d77ef7 to your computer and use it in GitHub Desktop.
Typing effect in React
import React, { useState, useEffect } from 'react';
const CONSTANTS = {
TYPING_SPEED: 30,
DELETING_SPEED: 150,
}
export default function TypeWriter({ messages, heading }) {
const [state, setState] = useState({
text: "",
message: "",
isDeleting: false,
loopNum: 0,
typingSpeed: 150,
});
useEffect(() => {
let timer = "";
const handleType = () => {
setState(cs => ({
...cs, // cs means currentState
text: getCurrentText(cs),
typingSpeed: getTypingSpeed(cs)
}));
timer = setTimeout(handleType, state.typingSpeed);
};
handleType();
return () => clearTimeout(timer);
}, [state.typingSpeed]);
useEffect(() => {
if (!state.isDeleting && state.text === state.message) {
setTimeout(() => {
setState(cs => ({
...cs,
isDeleting: true
}))
}, 500);
} else if (state.isDeleting && state.text === "") {
setState(cs => ({
...cs, // cs means currentState
isDeleting: false,
loopNum: cs.loopNum + 1,
message: getMessage(cs, messages),
}));
}
}, [state.text, state.message, state.isDeleting, messages]);
function getCurrentText(currentState) {
return currentState.isDeleting
? currentState.message.substring(0, currentState.text.length - 1)
: currentState.message.substring(0, currentState.text.length + 1);
}
function getMessage(currentState, data) {
return data[Number(currentState.loopNum) % Number(data.length)];
}
function getTypingSpeed(currentState) {
return currentState.isDeleting
? CONSTANTS.TYPING_SPEED
: CONSTANTS.DELETING_SPEED;
}
return (
<h1>
{heading}&nbsp;
<span>{state.text}</span>
<span id="cursor" />
</h1>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment