title: Why is first itteration skipped in setInterval?
body: <p>When I run the below function:</p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>import React, {useEffect, useState} from 'react';
  
  import classes from '../Main.module.css';
  
  export default function Intro() {
    // Timing Settings (for convenience)
      const highlightInterval = 50;
      const typingInterval = 75;
      const delayInterval = 1000;
    // ---------------------------------
  
    const greeterMsgE = 'Hello, it\'s nice to meet you...';
    const greeterMsgC = '你好, 很高兴认识你...';
  
    function makeSpanSequence(msg) {
      const _ = msg.split('');
      return _.map((char, i = 0) =&gt; (&lt;span key={i}&gt;{char}&lt;/span&gt;))
    }
  
    const [currentGreetMsg, setCurrentGreetMsg] = useState(makeSpanSequence(greeterMsgC))
    const [typerEngaged, setTyperEngaged] = useState(false)
  
    function greeterTyper() {
      function highlighter() {
        let index = currentGreetMsg.length
        const highTime = setInterval(() =&gt; {
          if (index &lt;= 0) {
            clearInterval(highTime)
            setTimeout(clearGreeting, delayInterval);
          } else {
            setCurrentGreetMsg(prev =&gt; {
              prev.splice(index, 1, (&lt;span key={index} className={classes.typerH}&gt;{currentGreetMsg[index].props.children}&lt;/span&gt;))
              return [...prev]
            })
            index--
          }
        }, highlightInterval);
      }
  
      function clearGreeting() {
        setCurrentGreetMsg([(&lt;br key={'br'} /&gt;)])
        setTimeout(typeNew, delayInterval)
      }
  
      function typeNew() {
        const newMessage = makeSpanSequence(greeterMsgE);
        let index = 0;
        setCurrentGreetMsg([newMessage[0]])
        const typeTime = setInterval(() =&gt; {
          if (index &gt;= newMessage.length){
            clearInterval(typeTime)
          } else {
            setCurrentGreetMsg(prev =&gt; {
              const _ = [...prev, newMessage[index]]
              return _
            })
            index++
          }
        }, typingInterval);
      }
  
      setTimeout(highlighter, 1500);
    }
  
    useEffect(() =&gt; {
      (typerEngaged ? greeterTyper() : setTyperEngaged(true))
    }, [typerEngaged])
  
  
    return (
      &lt;&gt;
      &lt;h2 className={classes.typerGreeting}&gt;{currentGreetMsg}&lt;/h2&gt;
  
      &lt;p&gt;    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.&lt;/p&gt;
      
      &lt;p&gt;
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      &lt;/p&gt;
  
      &lt;button&gt;More...&lt;/button&gt;
      &lt;/&gt;
    )
  }</code></pre>
  </div>
  </div>
  </p>
  <p>It types out the message as expected, but it seems to skip the first letter every time. I could set 'index' to -1 which fixes the immediate problem, but I am still unsure why it skipping 'setCurrentGreetMsg' on the first go.</p>
  <p>As far as I can tell, it literally skips it the first time, increments 'index' by one, then every subsequent time executes 'setCurrentGreetMsg' and then increments 'index' by one as expected.</p>