new to react, so bear with me.
Trying to make a animated typer with flashing | character at the end. The text will appear at random intervals but the | will be fixed.
Can anyone tell me why this isn't working. The flasher component works as expected, but the main text doesn't render, or renders one character then stops.
I've put a breakpoint on the useEffect in the Typer function and it only fires twice. But I've called updateTxt again?
I have tried to create a new object with updateTxt(Object.assign(txt) to see if that is the reason.
Maybe I'm doing it all wrong. Should I be using useRef and updating the element.current.innerText?
import {useEffect, useState} from "react";
import parse from 'html-react-parser';
function randomIntFromInterval(min, max) { // min and max included
return Math.floor(Math.random() * (max - min + 1) + min)
}
function Flasher(flash) {
const [flashval, updateFlash] = useState("<span>  </span>")
useEffect(() => {
if (flash) {
setTimeout(() => {
if (flashval === " |") {
updateFlash("<span>  </span>")
} else {
updateFlash(" |")
}
}, 375)
}
})
return (<>
{parse(flashval)}
</>)
}
export default function Typer({text, transform, flash, speed = 1}) {
const [txt, updateTxt] = useState({options: text.split("|"), index: 0, current_text: ""})
useEffect(() => {
let min = 1, max = 4
//get the full text required
let current_full_text = txt.options[txt.index]
//set the current text +1
txt.current_text = current_full_text.substring(0, txt.current_text.length + 1)
// logic if need to switch text or not
if (txt.current_text === current_full_text) {
// this will wait at the end of each word
txt.index++
// increases the index of the array and if too many then it resets to 0 and reset current text
if (txt.index > txt.options.length - 1) {
txt.index = 0
txt.current_text = ""
min = 4
max = 10
}
}
setTimeout(() => {
updateTxt(Object.assign(txt))
}, randomIntFromInterval(min, max) * 100 * speed)
})
return (<span>{txt.current_text}<Flasher flash/></span>)
}
<Typer speed="0.5" flash={true} text="test text 1|test me now|why are you not working"/>
There are several problems.
Object.assign:txt.current_text.length + 1works incorrectly. You can resetcurrent_text:And move this part down:
Working example