React-motion: Trying to understand willEnter / willLeave behavior.

Created on 12 Feb 2016  路  2Comments  路  Source: chenglou/react-motion

I'm trying to use React-Motion with Redux that uses the store as a global guide for components to know whether to activate or deactivate themselves.

I though I might use TransitionMotion as a way to define mounting and unmounting animations for components by passing in predefined arrays instead of lists of live data, like most of the examples given for TransitionMotion.

Under this method, components aren't ever truly unmounted, instead the "styles" array passed to TransitionMotion is just swapped between some content and a blank array.

However, with this method, mounting and unmounting animations fire correctly only once. Afterwards, the "unmounted" item remains on the DOM even after it is removed from the styles array, and the willLeave function loops infinitely.

I think I might be fundamentally misunderstanding how the TransitionMotion component interacts with styles array objects, and how it knows whether an object is leaving or entering.

This is the relevant code:

import React, {PropTypes} from 'react'
import { connect } from 'react-redux'
import {TransitionMotion, spring} from 'react-motion';
import classNames from 'classnames'
import { actions as UiActions } from '../../redux/modules/ui'
import classes from './CenterLogo.scss'

const mapStateToProps = (state) => ({
  MainView: state.ui.MainView
})

export class CenterLogo extends React.Component {
  static propTypes = {
    MainView: PropTypes.object.isRequired
  };

  componentWillUnmount(){
  }

  handleClick () {
    if(true){
      this.props.ToggleMainView()
    }
  }
  willLeave(key){
    console.log("leaving")
    return {
      opacity: spring(0),
    }
  }

  willEnter(key){
    console.log('entering')
    return {
      color: "red",
      opacity: spring(1),
      key
    }
  }

  getStyles(){
    if(this.props.MainView.active){
      return [{key: "CenterLogo", style: {opacity: spring(1, {stiffness: 10})}, data: Math.random()}]
    } else {
      return []
    }
  }

  render () {
    return (
      <TransitionMotion
        styles={this.getStyles()}
        willEnter={this.willEnter}
        willLeave={this.willLeave}
      >
        {interpolatedStyles => 
          <div>
            {interpolatedStyles.map(style => {
              return(
                <div key={style.key} style={style.style} className={classes.CenterLogo}>
                  <div className={classes.Logo}>
                    <div className={classes.Name}> Welcome </div> 
                    <div
                         onClick={this.handleClick.bind(this)} 
                         className={classes.h}> 
                      2
                    </div>
                    <div className={classes.Name}> Site </div> 
                  </div>
                </div>
              )
            })}
          </div>
        }
      </TransitionMotion>
    )
  }
}

export default connect(mapStateToProps, UiActions)(CenterLogo)

Most helpful comment

Check the type of willEnter here. Indeed, it's asking for a plain style configuration, e.g. {x: 10}, rather than {x: spring(10)}. Otherwise it's an error. Unfortunately it can't be checked through propTypes since it's a function If you use Flow you'd have caught it though.

willEnter only triggers once. willLeave is triggered a lot of times, until the current interpolation value reaches what you specified.

Hope that helps? Feel free to keep the questions coming =).

All 2 comments

I found a way around the problem, but am not quite clear why it works as it does.

I was setting the opacity of "willEnter" to a spring() value. By changing this value to a number, I was able to get animations to trigger consistently.

I think this may have something to do with willEnter and willLeave looping continuously until the element's style matches the style specified by the willEnter function.

Check the type of willEnter here. Indeed, it's asking for a plain style configuration, e.g. {x: 10}, rather than {x: spring(10)}. Otherwise it's an error. Unfortunately it can't be checked through propTypes since it's a function If you use Flow you'd have caught it though.

willEnter only triggers once. willLeave is triggered a lot of times, until the current interpolation value reaches what you specified.

Hope that helps? Feel free to keep the questions coming =).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

haxxxton picture haxxxton  路  4Comments

pizzarob picture pizzarob  路  6Comments

efdor picture efdor  路  3Comments

DanielRuf picture DanielRuf  路  4Comments

penx picture penx  路  4Comments