title: React JS: How to animate conditionally rendered components?
body: <p><strong>Example</strong> is a functional component in which I am rendering a <code>div</code> conditionally. I want this <code>div</code> to <strong>fade-in</strong> when rendered conditionally and <strong>fade-out</strong> vice versa.</p>
  
  <p>For that, I have maintained two local state variables: <code>render</code> and <code>fadeIn</code> which are computed based on <code>show</code> prop passed down to the <strong>Example</strong> component.</p>
  
  <p><strong>What I've done is:</strong></p>
  
  <ul>
  <li>When <code>show</code> prop it <strong>true</strong>, I set <code>render</code> as <strong>true</strong>, so the <code>div</code> renders conditionally and after a timeout of <code>10ms</code> I set <code>fadeIn</code>  as <strong>true</strong> which will set CSS classname for my div as <code>show</code>.</li>
  <li>When <code>show</code> prop it <strong>false</strong>, I set <code>fadeIn</code> as <strong>false</strong>, which will set CSS classname for my div as <code>hide</code> and after a timeout of <code>200ms</code> (transition time in CSS) I set <code>render</code>  as <strong>false</strong> so the <code>div</code> is hidden conditionally.</li>
  </ul>
  
  <p><strong>Code:</strong></p>
  
  <pre><code>interface Props {
    show: boolean;
  }
  
  const Example: React.FC&lt;Props&gt; = ({ show, }) =&gt; {
    const [render, setRender] = useState(false);
    const [fadeIn, setFadeIn] = useState(false);
  
    useEffect(() =&gt; {
      if (show) {
        // render component conditionally
        setRender(show);
  
        // change state to for conditional CSS classname which will
        // animate opacity, I had to give a timeout of 10ms else the
        // component shows up abruptly
        setTimeout(() =&gt; {
          setFadeIn(show);
        }, 10);
      } else {
        // change state to change component classname for opacity animation
        setFadeIn(false);
  
        // hide component conditionally after 200 ms
        // because that's the transition time in CSS
        setTimeout(() =&gt; {
          setRender(false);
        }, 200);
      }
    }, [
      show,
    ]);
  
    return (
      &lt;div&gt;
        {render &amp;&amp; (
          &lt;div className={`container ${fadeIn ? 'show' : 'hide'}`} /&gt;
        )}
      &lt;/div&gt;
    );
  };
  </code></pre>
  
  <p><strong>Stylesheet:</strong></p>
  
  <pre><code>.container {
    width: 100px;
    height: 100px;
    background-color: black;
    transition: opacity 0.2s ease;
  }
  
  .show {
    opacity: 1;
  }
  
  .hide {
    opacity: 0;
  }
  
  </code></pre>
  
  <p>I believe this is <strong>not a good coding practice</strong> to achieve the functionality and should maintain only one local state in my component. I need your <strong>suggestions</strong> on how I can solve this in a <strong>better way</strong> <strong>without using any 3rd Party Library</strong>.
  Thanks :)</p>