3

I have a simple checkbox, onClick of which I want to show and hide a div along with some transition delay using React. I can achieve the same effect when not using React. However when I use conditional rendering in react to render the div on click of checkbox. It does not show the effect. Here's the code which I have so far

import { useState } from "react";
import "./styles.css";

export default function App() {
  const [checkBox, setCheckBox] = useState(false);
  return (
    <div className="App">
      <input
        type="checkbox"
        checked={checkBox}
        onChange={() => setCheckBox(!checkBox)}
      ></input>
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      {checkBox && (
        <div
          style={{
            opacity: 1,
            transition: "height 2s",
            transitionTimingFunction: "ease-in"
          }}
        >
          Hey the checkbox is checked
        </div>
      )}
    </div>
  );
}

Codesandbox link - https://codesandbox.io/s/reverent-cartwright-gk11s?file=/src/App.js:0-659

Any help is much appreciated

Brijesh Prasad
  • 569
  • 6
  • 25

2 Answers2

2

It works for me. Try like this.

import { useState } from "react";
import "./styles.css";

export default function App() {
  const [checkBox, setCheckBox] = useState(false);
  return (
    <div className="App">
      <input
        type="checkbox"
        checked={checkBox}
        onClick={() => setCheckBox(!checkBox)}
      ></input>
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>

      <div className={checkBox ? "animate show" : "animate"}>
        Hey the checkbox is checked
      </div>
    </div>
  );
}

And in the css file...

.animate {
  height: 0px;
  overflow: hidden;
  transition: height 0.5s;
}
.show {
  height: 18px;
}

Please confirm here.

https://codesandbox.io/s/goofy-moon-ipe7t

BTSM
  • 1,585
  • 8
  • 12
  • 26
  • Thanks for the answer. Just one thing... if I set the height to `'fit-content'`, the transition animation is not applied. I want to set the height to the height of the content, how can I do that? – newbie Jun 06 '22 at 18:54
  • 1
    please confirm this URL if you don't understand the fit-content. https://stackoverflow.com/questions/52337025/no-css-transition-for-height-fit-content – BTSM Jun 07 '22 at 00:48
0

So for transitions to work on conditionally rendered components, you have to access the component's lifecycle to check if it was rendered before adding your styling. You can either use separate life cycle methods (ComponentDidMount(), ComponentDidUpdate(), ComponentWillUnmount()) or useEffect hook which is basically a combination of multiple lifecycle methods mentioned above. for example, useEffect will always run after component was rendered, so you can have state change inside useEffect to add your class to the component.

Parent Component:

import CondtionalComponent from "../CondtionalComponent";
import { useState } from "react";

const ParentComponent = () => {
  const [showComponent, setShowComponent] = useState(false);

  return (
       <div>
          <button
            onClick={() => setShowComponent((prevState) => !prevState)}
          >
          </button>
          {showComponent && (
            <CondtionalComponent/>
          )}
        </div>
  );
};

export default ParentComponent;

ConditionalComponent:

import {useEffect, useState) "react"

const CondtionalComponent = () => {
      const [animate, setAnimate] = useState(false)

      useEffect(()=>{
          setAnimate(true)
          //empty dependencies list means it will only run after first render
      },[])
      

      return(<div className={animate ? "show" : ""}>"whatever"</div>)
}

export default CondtionalComponent

If you are planning to use a lot of animations after rendering and before unmounting I suggest to use ReactTransitionGroup. More about it here:

https://reactjs.org/docs/animation.html

Hope it helps:)

Jovaras
  • 1
  • 1