Boky Boky - 3 months ago 34
React JSX Question

Animations with React JS

I have a few sort filters on my page, and I want to create animation when user click on one of them.

If user want to sort by the lowest price, I want to show the new list, but with some animations.

I try to do it with React JS.

On componentWillMount I set the state with all cars :

componentWillMount(){
const cart = this.props.cart;
const listID = this.props.params.id;
const allCars = data.getAllCars();
let offers = this.state.offers;

cart.map(car => {
const aCar = allCars.find(c => {
return c.id === car.carID;
});
offers[aCar.chassis] = car.offer;
this.setState({offers: offers});
});


//We set state with all cars in this list
const cars = carData.getCarsInCurrentList(listID, allCars);
this.setState({cars: cars});
}


and then when user clicks on one of the sort filters I handle it on this function :

handleSortingFilters(name, event){

event.preventDefault();
const cars = this.state.cars;
const sortFilterValue = this.state.sortFiltersInit[name];
let filteredCars = "";

if(sortFilterValue){
//descending order
filteredCars = cars.sort((a, b) => {
if(name === "initialRegistration"){
return Date.parse(b[name]) - Date.parse(a[name]);
}else{
return parseFloat(b[name]) - parseFloat(a[name]);
}
});
}else{
//ascending order
filteredCars = cars.sort((a, b) => {
if(name === "initialRegistration") {
return Date.parse(a[name]) - Date.parse(b[name]);
}else{
return parseFloat(a[name]) - parseFloat(b[name]);
}

});
}

let sortFiltersInit = this.state.sortFiltersInit;
sortFiltersInit[name] = !this.state.sortFiltersInit[name];

let allFilters = this.state.allFilters;
allFilters[name] = name;

this.setState({cars: filteredCars, sortFiltersInit: sortFiltersInit, allFilters: allFilters});
}


Thus, I update the state with the filtered list of cars. Everything works perfect, but I would like also to apply some css animations on the list when user clicks on one of the sort filters.

Any ideas or link to some good tutorials?

Thanks.

UPDATE

The list where the cars are rendered :

<div className="cars">
<div>
<ReactCSSTransitionGroup
transitionName="example"
transitionAppear={true}
transitionAppearTimeout={500}
transitionEnterTimeout={500}
transitionLeaveTimeout={500}>

{cars.map((car, i) => {
const initialReg = car.initialRegistration.slice(0,3) + car.initialRegistration.slice(6,10);
// str.slice(1, 4) extracts the second character through the fourth character (characters indexed 1, 2, and 3)

return (
<div key={i} className="carBox noPadding">
<div className="carBoxContent">

<PhotoAndFavorites car={car} language={language} changeStarIcon={this.changeStarIcon} addToFavorites={addToFavorites} userEmail={currentUserEmail} favorites={favorites}/>

<div className="carNameAndDesc">
<div><Link to="" style={{textDecoration: 'none'}}>{car.make}</Link></div>
<div>{car.desc}</div>
</div>

<div className="carPrice">
<div>{car.price}</div>
<div>{car.btw}</div>
</div>

<div className="extraFeatures" style={{marginBottom: 5, backgroundColor: '#eee'}}>

</div>

<div className="mainFeatures">
<div><img src="../images/portal/user/status/fuel-icon.png" style={{height: 12}}/> <span>{car.fuel}</span></div>
<div><img src="../images/portal/user/status/road-icon.png" style={{height: 12}}/> <span>{car.mileage}</span></div>
<div><img src="../images/portal/user/status/calendar-icon.png" style={{height: 12}}/> <span>{initialReg}</span></div>
</div>

<Buttons car={car}
language={language}
changeButton={this.changeButton}
addToCard={addToCard}
removeFromCard={removeFromCard}
cartContent={cartContent}
userEmail={currentUserEmail}
handleChange={handleOffers}
offers={offers}
opacity={this.props.opacity}
/>

</div>
</div>
);
})}
</ReactCSSTransitionGroup>
</div>
<div className="clearfix"/>
</div>


I added also this css :

.example-appear {
opacity: 0.01;
}

.example-appear.example-appear-active {
opacity: 1;
transition: opacity .5s ease-in;
}

Answer

You can use react-addons-css-transition-group

ReactCSSTransitionGroup is based on ReactTransitionGroup and is an easy way to perform CSS transitions and animations when a React component enters or leaves the DOM. It's inspired by the excellent ng-animate library.

This will trigger a transition in your main layout every time you change a route

css

.example-enter {
  opacity: 0.01;
  transition: opacity .5s ease-in;
}

.example-enter.example-enter-active {
  opacity: 1;
}

.example-leave {
  opacity: 1;
  transition: opacity .5s ease-in;
}

.example-leave.example-leave-active {
  opacity: 0;
}

js

import React from 'react'
import ReactCSSTransitionGroup from 'react-addons-css-transition-group'

render() {
  return(
    <ReactCSSTransitionGroup
      component="ul"
      transitionName="example"
      transitionEnterTimeout={500}
      transitionLeaveTimeout={500}>
      {this.state.cars.map(car => <li key={car.id}>{car.name}</li>)}
    </ReactCSSTransitionGroup>
  )
}

If you need a shuffle animation try react-shuffle - Animated shuffling of child components

import React, {Component} from 'react';
import Shuffle from 'react-shuffle';

class App extends Component {
  render() {
    return (
      <Shuffle>
        {// Method to render children goes here}
      </Shuffle>
    )
  }
}