title: Trying to create React component with textarea that auto expands and shrinks based on content height (with Sandbox)
body: <p>I'm trying to build this <code>TextArea</code> component that uses React hook and <code>styled-components</code>.</p>
  
  <p>Everything goes well when my <code>textarea</code> is gaining new lines. The expand feature is working as expected.</p>
  
  <p>What I'm doing, basically, is:</p>
  
  <ul>
  <li>Using <code>textAreaRef</code>- <code>useRef()</code> to store a ref to the <code>textarea</code> element</li>
  <li>Using <code>lastScrollHeight</code>- <code>useRef()</code> to store the last <code>ScrollHeight</code></li>
  <li>Using <code>idealHeight</code>- <code>useRef()</code> to store the ideal height for the <code>textarea</code></li>
  </ul>
  
  <p>I calculate the <code>idealHeight</code> based on the value of the <code>lastScrollHeight</code> that has been stored on the previous render. Then I compare with the current value of <code>textAreaRef.current.scrollHeight</code> and I calculate the <code>delta</code>.</p>
  
  <p>Then I calculate the <code>idealHeight.current = idealHeight.current + delta</code> and send it as <code>props</code> to my styled-component <code>TextAreaInput</code> to set the <code>height</code>.</p>
  
  <p><strong>THE PROBLEM</strong></p>
  
  <p><code>scrollHeight</code> increases when new lines are added and returns a positive <code>delta</code>. But <code>scrollHeight</code> doesn't decrease when lines are removed. So <code>delta</code> comes back zero.</p>
  
  <p>I need a way to measure the height of the text content inside of the <code>textarea</code>. I saw some questions here on SO that recommended to do this by setting <code>height</code> of the element to a very small value before asking for the <code>scrollHeight</code>.</p>
  
  <p>Indeed, that gives me the negative <code>deltas</code> that I want, but that just stops any expanding or shrinking, and I get a scroll bar instead. See that by toggling the commented line <code>textAreaRef.current.style.height = "2px";</code>. Some how the component gets stuck on <code>height='2px'</code>. I don't know.</p>
  
  <p><a href="https://codesandbox.io/s/4xqp39nqx" rel="nofollow noreferrer">Code SandBox with working example</a> (mind the console logs)</p>
  
  <p>Any ideas what's going wrong?</p>
  
  <p><strong>TextArea.js</strong></p>
  
  <pre><code>import React, { useRef } from "react";
  import styled from "styled-components";
  
  const TextAreaInput = styled.textarea`
    height: ${props =&gt; props.idealHeight || "152px"};
    min-height: 32px;
    max-height: 320px;
    line-height: 21px;
    width: 100%;
    resize: vertical;
    box-sizing: border-box;
  
    border: 1px solid rgb(217, 217, 217);
    padding: 4px 11px;
    text-size-adjust: 100%;
  `;
  
  function TextArea(props) {
    const idealHeight = useRef(32);
    const lastScrollHeight = useRef(30);
    const textAreaRef = useRef(null);
  
    console.log("ANOTHER RENDER...");
  
    if (textAreaRef.current !== null &amp;&amp; textAreaRef.current !== undefined) {
      const scrollHeight = textAreaRef.current.scrollHeight;
  
      // THIS NEXT LINE MAKES THE DELTA CALCULATION CORRECT ON 'SHRINKING'
      // BUT STOPS THE RESIZING
  
      // textAreaRef.current.style.height = "2px";
  
      const delta = scrollHeight - lastScrollHeight.current;
      console.log("Delta is: " + delta);
  
      console.log("Last ScrollHeight: " + lastScrollHeight.current);
      lastScrollHeight.current = scrollHeight;
  
      console.log("Current ScrollHeight: " + lastScrollHeight.current);
  
      idealHeight.current = idealHeight.current + delta;
  
      console.log("IdealHeight :" + idealHeight.current);
    }
  
    return (
      &lt;TextAreaInput
        placeholder={props.placeholder}
        value={props.value}
        onChange={e =&gt; props.setValue(e.target.value)}
        ref={textAreaRef}
        idealHeight={idealHeight.current + "px"}
      /&gt;
    );
  }
  
  export default TextArea;
  </code></pre>