Состояние компонента должно содержать три значения - индекс печатаемой строки, количество отображаемых символов, направление печати (печатаем или стираем, т.е., в какую сторону надо изменять количество отображаемых символов, увеличивать или уменьшать). Дальше понятно что - setInterval или рекурсивный setTimeout, изменяем количество отображаемых символов, если дошли до конца строки - меняем направление, дошли до начала - меняем направление и индекс строки.
Вот как-то так:
const defaults = {
index: 0,
length: 0,
step: 1,
};
function Typewriter({ strings, delay }) {
const [ state, setState ] = useState(null);
useEffect(() => {
setState(() => ({...defaults}));
}, [ strings ]);
useEffect(() => {
const timeoutId = setTimeout(setState, delay, ({...state}) => {
state.length += state.step;
if (state.length === strings[state.index].length) {
state.step = -1;
} else if (state.length === 0) {
state.step = 1;
state.index = (state.index + 1) % strings.length;
}
return state;
});
return () => clearTimeout(timeoutId);
});
return <div>{strings?.[state?.index]?.slice(0, state?.length)}</div>;
}