React note #17

Yechan Jeon·2022년 1월 1일
0

React dev

목록 보기
17/18
post-thumbnail

Animating React Apps


CSS transition & animations limitations.

If we use CSS animation effect, we always have elements related to style on browser. The animiation may be pretty fine though.
Sure, we can figure out this with showing component according to ternary condition. But in the perspective of whole animation process, there may be some unexpected side effect because our component will be removed instantly according to condition.

To manage this problem, we can use third-party package.

React-transition-group

npm install react-transition-group --save
1.Transition
import Transition from "react-transition-group/Transition";
Wrap component with 'Transition'

<Transition in={this.state.showBlock} timeout={300}>
          {(state) => <p>{state}</p>}
</Transition>

In the 'in' prop, when this.state.showBlock is true, div will be rendered.(It is kind of condition.)
Inside of Transition component, you can use state variable which has four state (entering , entered, exiting, exited).
The process is really simple.
1. exited -> entering -> entered
2. entered -> exiting -> exited
You can check this from the line {(state) => <p>{state}</p>}

Here is more realistic example

        <Transition
          in={this.state.showBlock}
          timeout={300}
          mountOnEnter
          unmountOnExit
        >
          {(state) => {
            return (
              <div
                style={{
                  backgroundColor: "red",
                  width: 100,
                  height: 100,
                  margin: "auto",
                  transition: "opacity 0.3s ease-out",
                  opacity: state === "exiting" ? 0 : 1,
                }}
              ></div>
            );
          }}
        </Transition>

'mountOnEnter' props makes wrapped component shown only when 'in' prop has true.
'unmountOnExit' works exactly in an opposite way.
Finally, you can use state to apply animation into your element.

If you wanna give different timing with entering and exiting, you can set timing object with reserved property

const dynamicTiming = {
  enter: 400,
  exit: 1000,
};
const modal = (props) => {
  return (
    <Transition
      in={props.show}
      timeout={dynamicTiming}
      mountOnEnter
      unmountOnExit
    >
      ...some code
    </Transition>

Here are more props for 'Transition'

<Transition
      in={props.show}
      timeout={dynamicTiming}
      mountOnEnter
      unmountOnExit
      onEnter={() => console.log("onEnter")}
      onEntering={() => console.log("onEntering")}
      onEntered={() => console.log("onEntered")}
      onExit={() => console.log("onExit")}
      onExiting={() => console.log("onExiting")}
      onExited={() => console.log("onExited")}
    >

with onSomeTiming event, you can control every step of transition.
The order of execution is :
onEnter -> onEntering -> onEntered
onExit -> onExiting -> onExited

  1. CSSTransition

import CSSTransition from "react-transition-group/CSSTransition";

return (
    <CSSTransition
      in={props.show}
      timeout={dynamicTiming}
      mountOnEnter
      unmountOnExit
      classNames="fade-slide"
    >
      <div className="Modal">
        <h1>A Modal</h1>
        <button className="Button" onClick={props.closed}>
          Dismiss
        </button>
      </div>
    </CSSTransition>
  );
};

There is no state function anymore. Instead, we can use 'classNames' prop.
This classNames will add extended className during transition process.
For example,
fade-slide -> fade-slide-enter(start) -> fade-slide-enter-active(entering) -> fade-slide(entered)
The exiting process is similar.

Your role is just add this classes in your css file.

.fade-slide-enter {
}

.fade-slide-enter-active {
  animation: openModal 0.4s ease-out forwards;
}

.fade-slide-exit {
}

.fade-slide-exit-active {
  animation: closeModal 1s ease-out forwards;
}

Keep in mind that 'enter' and 'exit' style will be removed instantly according to your modal state. If you want to keep animation, give it to active classes.

On the other hand, you also can customize these css classes trunk.

    <CSSTransition
      in={props.show}
      timeout={dynamicTiming}
      mountOnEnter
      unmountOnExit
      classNames={{
        enter: "",
        enterActive: "ModalOpen",
        exit: "",
        exitActive: "ModalClosed",
      }}
    >

You also can use 'appear' and 'appearActive' property for when your component is mounted on the browser at the first time.

  1. TransitionGroup

This can be used for animating kind of list items
TransitionGroup

profile
방황했습니다. 다시 웹 개발 하려고요!

0개의 댓글