0
votes

I'm facing this issue in which if I don't wrap an element with CSS transition into a React child component then it runs the transition smoothly and if I wrap it into a child component it doesn't show the transition at all.

App.js

...

const [pb, setPb] = React.useState("0");

if (pb == 0) {
  setTimeout(() => {
    setPb("60");
  }, 1000);
}

const AnotherBall = () => {
  return (
    <div
      className="ball2"
      style={{
        top: `${pb}%`
      }}
    ></div>
  );
};

return (
  <div className="App">
    <div
      className="ball"
      style={{
        top: `${pb}%`
      }}
    ></div>
    <AnotherBall />
  </div>
);

style.css

...

.ball,
.ball2 {
  position: absolute;
  top: 0;
  left: 0;
  width: 100px;
  height: 100px;
  background: #ff5f5f;
  border-radius: 50%;
  transition: all 1s ease-in-out;
}

.ball2 {
  left: 90%;
  background: #ff5f5f;
}

sandbox: https://codesandbox.io/s/boring-wescoff-jcxgw?file=/src/App.js

1

1 Answers

1
votes

Don't declare components inside the body of other components. Every time a component rerenders the functions it contains are redeclared, meaning they are not referentially stable from one render to the next. AnotherBall in your example is being unmounted and remounted with the new value because React thinks it's a new component.

Instead, move the component outside of App and pass the required value as a prop like this:

// App.js

<AnotherBall pb={pb} />
// AnotherBall.js

const AnotherBall = ({pb}) => {
  return (
    <div
      className="ball2"
      style={{
        top: `${pb}%`
      }}
    ></div>
  );
};