devstory

Exemple React-Transition-Group Transition (NodeJS)

  1. L'objectif de la leçon
  2. Créer un projet et installer la bibliothèque
  3. L'exemple avec Transition simple
  4. Exemple de Transition (unmountOnExit)

1. L'objectif de la leçon

La bibliothèque react-transition-group vous fournit des composants pour que vous puissiez créer des effets d'animation dans l'application React. La publication détaillée ci-dessous introduit de la bibliothèque, de ses composants qu'elle fournit, des API,..
Dans cette leçon, je vais vous montrer quelques exemples avec les composants Transition& TransitionGroup fournis par la bibliothèque react-transition-group.
Un autre composant similaire est CSSTransition qui vous permet de travailler plus facilement avec CSS transition :

2. Créer un projet et installer la bibliothèque

Créez un projet React nommé transition-app en exécutant les commandes ci-dessous :
# Install 'create-react-app' tool (If it has never been installed)

npm install -g create-react-app

# Create project with 'create-react-app' tool:

create-react-app transition-app
Installer la bibliothèque react-transition-group :
# CD to your project

cd transition-app

# Install 'react-transition-group':

npm install react-transition-group --save
Exécutez votre application :
# Run app:

npm start

3. L'exemple avec Transition simple

Voici l'aperçu de cet exemple :
  • Lorsque la valeur de 'in' change de false à true, le composant <Transition> va changer en statut 'entering', et reste dans ce statut en 'timout' milisecondes, puis il change en statut 'entered'.
  • Lorsque la valeur de 'in' change de true à false, le composant <Transition> va changer en staut 'exiting', et reste dans ce statut en 'timout' milisecondes, puis il change en statut 'exited'.
OK, revenez au projet ci-dessus. Supprimez tout le contenu des fichiers App.js & App.css :
App.css
.my-msg {
   color: blue;
}

.my-msg-entering {
    color: blue;
    font-size: 150%;
    transition-duration: 1s;
 }

 .my-msg-entered {
    font-size: 150%;
    color: red;
 }

.my-msg-exiting {
    font-size: 100%;
    color: black;
    transition-duration: 1s;
}

.my-highlight  {
  color: red;
}
App.js
import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";

import {
  TransitionGroup,
  CSSTransition,
  Transition
} from "react-transition-group";

class App extends React.Component {
  render() {
    return (
      <div>
        <MyComponent />
      </div>
    );
  }
}

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      stateOfIn: false,
      message: ""
    };
  }

  // Begin Enter: Do something here!
  onEnterHandler() {
    console.log("Begin Enter");
    this.setState({ message: "Begin Enter..." });
  }

  onEnteringHandler() {
    console.log("Entering... (Wait timeout!)");
    this.setState({ message: "Entering... (Wait timeout!)" });
  }

  onEnteredHandler() {
    console.log("OK Entered!");
    this.setState({ message: "OK Entered!" });
  }

  // Begin Exit: Do something here!
  onExitHandler() {
    console.log("Begin Exit");
    this.setState({ message: "Begin Exit..." });
  }

  onExitingHandler() {
    console.log("Exiting... (Wait timeout!)");
    this.setState({ message: "Exiting... (Wait timeout!)" });
  }

  onExitedHandler() {
    console.log("OK Exited!");
    this.setState({ message: "OK Exited!" });
  }

  render() {
    return (
      <div>
        <h3>&lt;Transition in={"{this.state.stateOfIn}"} &gt;</h3>

        <b>{"\u2728"} Focus on Textfield and see the effects:</b>
        <ul>
          <li className="my-highlight">
            Now 'in' = {String(this.state.stateOfIn)}
          </li>
          <li> false --&gt; true (Enter)</li>
          <li> true --&gt; false (Exit)</li>
        </ul>
        <div className="my-highlight">{this.state.message}</div>

        <br />

        <input
          type="text"
          onFocus={() => {
            this.setState({ stateOfIn: true });
          }}
          onBlur={() => {
            this.setState({ stateOfIn: false });
          }}
        />
        <br />

        <Transition
          in={this.state.stateOfIn}

          timeout={{ enter: 1500, exit: 2500 }}
          onEnter={() => this.onEnterHandler()}
          onEntering={() => this.onEnteringHandler()}
          onEntered={() => this.onEnteredHandler()}
          onExit={() => this.onExitHandler()}
          onExiting={() => this.onExitingHandler()}
          onExited={() => this.onExitedHandler()}
        >
        {(statusName) => (
           <div className={`my-msg my-msg-${statusName}`} >User name 2-20 characters</div>
        )}
        </Transition>
      </div>
    );
  }
}

export default App;
Il n'est pas nécessaire de changer les contenus du fichier index.js & index.html :
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<App />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
serviceWorker.unregister();
index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#000000">
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
    <title>React CssTransition</title>
  </head>
  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <div id="root"></div>
  </body>
</html>
Exemple 2 :
Avec toujours l'exemple ci-dessous, nous changez les contenus du App.css comme ci-dessous pour créer un effet plus complexe :
App.css (Edited) (2)
.my-msg {
   color: blue;
   margin-left: 300px;
   opacity: 0;
}

 .my-msg-entering {
    color: blue;
    margin-left: 0px;
    opacity: 1;
    font-size: 150%;
    transition-duration: 1s;
 }

 .my-msg-entered {
    opacity: 1;
    margin-left: 0px;
    font-size: 150%;
    color: red;
 }

.my-msg-exiting {
    opacity: 0;
    font-size: 100%;
    margin-left: 300px;
    color: black;
    transition-duration: 1s;
}

.my-highlight  {
  color: red;
}

4. Exemple de Transition (unmountOnExit)

<ReactTransitionGroup.Transition  unmountOnExit = {true/false} mountOnEnter = {true/false}>

    <!-- Child Component -->
    <MySingleElement>
       <MyOtherElements />
    </MySingleElement>

</ReactTransitionGroup.Transition>
L'avant-première de cet exemple :
App3.css
.my-msg-entering {
    color: blue;
 }

 .my-msg-entered {
    color: red;
 }

.my-highlight  {
  color: red;
}
App3.js
import React, { Component } from "react";
import logo from "./logo.svg";
import "./App3.css";

import {
  TransitionGroup,
  CSSTransition,
  Transition
} from "react-transition-group";

class App extends React.Component {
  render() {
    return (
      <div>
        <MyComponent />
      </div>
    );
  }
}

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      stateOfIn: false,
      message: ""
    };
  }

  // Begin Enter: Do anything!
  onEnterHandler() {
    console.log("Begin Enter");
    this.setState({ message: "Begin Enter..." });
  }

  onEnteringHandler() {
    console.log("Entering... (Wait timeout!)");
    this.setState({ message: "Entering... (Wait timeout!)" });
  }

  onEnteredHandler() {
    console.log("OK Entered!");
    this.setState({ message: "OK Entered!" });
  }

  // Begin Exit: Do anything!
  onExitHandler() {
    console.log("Begin Exit");
    this.setState({ message: "Begin Exit..." });
  }

  onExitingHandler() {
    console.log("Exiting... (Wait timeout!)");
    this.setState({ message: "Exiting... (Wait timeout!)" });
  }

  onExitedHandler() {
    console.log("OK Exited!");
    this.setState({ message: "OK Exited!" });
  }

  render() {
    return (
      <div>
        <h3>&lt;Transition in={"{this.state.stateOfIn}"} &gt;</h3>

        <b>{"\u2728"} Click the buttons and see the effects:</b>
        <ul>
          <li className="my-highlight">
            Now 'in' = {String(this.state.stateOfIn)}
          </li>
          <li> false --&gt; true (Enter)</li>
          <li> true --&gt; false (Exit)</li>
        </ul>
        <div className="my-highlight">{this.state.message}</div>

        <br />

        <input
          type="text"
          onFocus={() => {
            this.setState({ stateOfIn: true });
          }}
          onBlur={() => {
            this.setState({ stateOfIn: false });
          }}
        />
        <br />

        <Transition
          in={this.state.stateOfIn}

          unmountOnExit

          timeout={{ enter: 1500, exit: 2500 }}
          onEnter={() => this.onEnterHandler()}
          onEntering={() => this.onEnteringHandler()}
          onEntered={() => this.onEnteredHandler()}
          onExit={() => this.onExitHandler()}
          onExiting={() => this.onExitingHandler()}
          onExited={() => this.onExitedHandler()}
        >
          {stateName => {
            // stateName: 'entering', 'enterd', 'exiting', 'exited'
            switch (stateName) {

              case "entering":
                return (
                  <b className="my-msg-entering">
                    ⭐ Note: User name 2-20 characters
                  </b>
                );
              case "entered":
                return (
                  <b className="my-msg-entered">
                    ⭐ Note: User name 2-20 characters
                  </b>
                );
              case "exiting":
                return <div>(User Name)</div>;
              case "exited":
                return <b>(User Name)</b>;
              default:
                return <div>??</div>;
            }
          }}
        </Transition>
      </div>
    );
  }
}

export default App;
Changez le contenu du fichier index.js :
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

import App from './App3'; // IMPORTANT!
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<App />, document.getElementById('root'));

serviceWorker.unregister();