title: React hooks functions have old version of a state var
body: <p>I tried to make a nice animating example for myself using Hooks but I have stumbled upon a problem where my functions won't have the updated version of a state var and continue to use the first version.</p>
  
  <p>In the snippet below I have an example where once you click on a bar it's supposed to move in a square formation. First going east, then south, then west, then north and then east again etc. However it never goes south because even though its direction is updated from <code>north</code> to <code>east</code> (indicated by the text on the bar or clicking on it again), the functions still think that the direction is north. </p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="true">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>const Example = (props) =&gt; {
    const [ direction, setDirection ] = React.useState('North');
    console.log("Rendering Example: ", direction);
    
    const isAnimating = React.useRef(false)
    const blockRef = React.useRef(null);
    
    // Animate on click.
    const onClick = () =&gt; {
      if (!isAnimating.current) {
        decideDirection();
        isAnimating.current = true
      } else {
        console.log("Already animating. Going: ", direction);
      }
    };
    
    const decideDirection = () =&gt; {
      console.log("Current direction: ", direction);
      if (direction === 'North') {
        moveEast();
      } else if (direction === 'East') {
        moveSouth();
      } else if (direction === 'South') {
        moveWest();
      } else if (direction === 'West') {
        moveNorth();
      }
    };
    
    const move = (toX, toY, duration, onComplete) =&gt; {
      Velocity(blockRef.current, {
        translateX: toX,
        translateY: toY,
        complete: () =&gt; {
          onComplete();
        }
      },
      {
        duration: duration
      });
    }
    
    const moveNorth = () =&gt; {
      setDirection('North');
      console.log('Moving N: ', direction);
      move(0, 0, 500, () =&gt; {
        decideDirection();
      })
    }
    
    const moveEast = () =&gt; {
      setDirection('East');
      console.log('Moving E: ', direction);
      move(500, 0, 2500, () =&gt; {
        decideDirection();
      })
    };
    
    const moveSouth = () =&gt; {
      setDirection('South');
      console.log('Moving S: ', direction);
      move(500, 18, 500, () =&gt; {
        decideDirection();
      })
    }
    
    const moveWest = () =&gt; {
      setDirection('West');
      console.log('Moving W: ', direction);
      move(0, 18, 2500, () =&gt; {
        decideDirection();
      })
    }
    
    return(
      &lt;div&gt;
        &lt;div id='block' onClick={onClick} ref={blockRef} style={{ width: '100px', height: '18px', backgroundColor: 'red', textAlign: 'center'}}&gt;{direction}&lt;/div&gt;
      &lt;/div&gt;
    );
  };
  
  ReactDOM.render(&lt;div&gt;&lt;Example/&gt;&lt;/div&gt;, document.getElementById('root'));</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.2/velocity.min.js"&gt;&lt;/script&gt;
  
  &lt;script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"&gt;&lt;/script&gt;
  &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"&gt;&lt;/script&gt;
  &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"&gt;&lt;/script&gt;
  
  &lt;div id='root' style='width: 100%; height: 100%'&gt;
  &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>I find this kind of strange because none of these functions are memoized so they should re-create every render and thus have the new value. Even if I do add something like <code>useCallback</code> and provide <code>direction</code> to every function it still won't work. Why don't the functions know about the updated version of the state var?</p>