Animation i React med React Transition Group

Häromdagen jobbade jag på ett nytt projekt utvecklat i React. En del av mitt jobb var att översätta statisk HTML till interaktiva React-components. Jag ville liva upp applikationen lite genom att använda animering.

Under lång tid sköttes det hela perfekt av jQuery. Men med uppkomsten av nya JavaScript-frames, som React och Angular, så försvann möjligheterna med jQuery. DOM-manipulation i React fungerar annorlunda. Komponenterna har livscykler som kan hoppa in och ut ur DOM.

Efter lite research kom jag över några animeringsbibliotek som exempelvis React Transition Group, React-spring, React-motion och andra. Vart och ett av dessa bibliotek har sina för- och nackdelar, några av dem var helt enkelt bara för krångliga att använda. Allt beror dock på projektets behov. Jag ville lägga till snygga bild- och övergångseffekter till vissa element. Det är egentligen en ganska enkel animering så jag bestämde mig för att välja React Transition Group  just på grund av dess enkelhet.

React Transition Group brukade vara en React add-on. Nu är det separerat och underhålls av communityn.

Jag vill nämna att React Transition Group-komponenterna inte ger oss själva animationen. I stället ger det oss en state för varje lifecycle så att vi kan tillämpa CSS-animering på komponenten när den ändrar state.

Låt oss ta en titt på hur det fungerar i praktiken. Jag har skapat en enkel sidebar. Den är gömd som standard och triggas av en knapp. När knappen klickas kommer komponenten att ändra state och producera en side bar.

import React, { Component } from "react";
import { render } from "react-dom";


class App extends Component {
//Initial state
 state = {
  show: false
 };

//Toggle show/hide sidebar
 toggleShow() {
  this.setState({
   show: !this.state.show
  });
 }

//Rendering sidebar
renderSidebar() {
 if(this.state.show) {
  return (
   <div
    style={{
     width: "50%",
      height: "100vh",
      paddingTop: '10px',
      background: "green",
      color: "white",
      textAlign: "center",
      transition: "all 1s ease",
      position: "absolute",
      top: 0,
      left: 0
     }}
    >
     Hi, there!
    </div>
   )
  } else {
    return null
   }
  }


 render() {
  return (
   <React.Fragment>
    {this.renderSidebar()}

    <button
     onClick={() => this.toggleShow()}
     style={{float: "right"}}>
      Button
    </button>

   </React.Fragment>
  );
 }
}


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

Nu har vi fått igång det. Vi lägger till en fin slide effect när side bar dyker upp. Vi använder <Transition /> component. Låt oss först installera paketet och importera <Transition /> component till vår App.

npm install react-transition-group --save

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

Komponenten <Transition /> component kan finnas i fyra tillstånd: “Enter”, “entered”, “exiting” och “exited”. Det låter oss se dess beteende när det passerar från ett state till ett annat. Det tar också två huvudsakliga props: “timeout” och “in”.

I “timeout” -protokollet ställer vi in övergången i millisekunder. “In” -prop kommer att spåra staten. När “in” -värdet är lika med “true” flyttas en komponent till “in” -state och stannar där i 500ms innan man växlar till “inmatat” tillstånd. Samma process händer när “in” -värdet är lika med “false” – först flyttas en komponent till “exiting” och sedan till “exited” -state.

En annan viktig detalj jag vill nämna är att <Transition /> component returnerar en funktion med state som ett argument. Att placera children elements i det kommer inte att fungera.

Här är slutkoden.

import React, { Component } from "react";
import { render } from "react-dom";

//Import Transition component
import Transition from "react-transition-group/Transition";


class App extends Component {
//Initial state 
state = {
  show: false
 };

//Toggle show/hide sidebar
 toggleShow() {
  this.setState({
   show: !this.state.show
  });
 }


//Rendering sidebar
renderSidebar() {
 return (
  <Transition in={this.state.show} timeout={1000}>
   {state => (
    <div
     style={{
      width: "50%",
      height: "100vh",
      paddingTop: "10px",
      background: "green",
      color: "white",
      textAlign: "center",
      transition: "all 1s ease",
      position: "absolute",
      top: 0,
      //This is where all the magic happens 🙂
      left: state === "entering" || state === "entered" ? 0 : "-50%"
     }}
    >
     Hi, there!
    </div>
   )}
  </Transition>
 )
}


render() {
 return (
  <React.Fragment>
   {this.renderSidebar()}

   <button
    onClick={() => this.toggleShow()}
    style={{ float: "right" }} >
     Button
   </button>

  </React.Fragment>
  );
 }
}


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

Som du kan se har jag justerat “renderSidebar ()” -funktionen. Jag har wrappat sidofältet med <Transition/> komponenten där “in” -prop lagrar staten och “timeout” är inställd på 1000ms. Allt det magiska sker på CSS ” “left” property. När state är lika med “inmatning” eller “inmatad” så tar den 0 och komponenten blir synlig. Annars flyttas den bort med -50 % (i förhållande till dess bredd) och blir osynlig.

Så här fungerar React Transition Group. Vi gör animationen med hjälp av CSS. Självfallet kan vi göra mycket mer med det. React Transition Group ger oss också andra komponenter så som <CSSTransition /> och <TransitionGroup /> där vi kan lägga till egna namn eller animera element i en lista.

Sammanfattningsvis vill jag säga att React Transition Group är ett utmärkt val för enkla animeringar.

/ Anastasia

Origin: www.linkedin.com

Alla artiklar