Chet
Chet

Reputation: 19889

React Animations with VelocityJS

I'm having a really hard time getting animations to work in React. Perhaps there is something I'm fundamentally missing.

I'm doing this in coffeescript -- I hope you don't mind.

I've created a very simple UI. Theres a div with a title in it. When you click the title, the title is changed, and I want to animate a fade in/out transition using VelocityJS.

ReactTransitionGroup = React.createFactory(React.addons.CSSTransitionGroup)

{div} = React.DOM

TitleClass = React.createClass
  displayName: "Title"
  render: ->
    (div {onClick:@props.changeTitle}, @props.title)

  componentWillEnter: (done) ->
    node = @getDOMNode()
    console.log "willEnter"
    Velocity(node, 'transition.fadeIn', {complete: done})

  componentWillLeave: (done) ->
    node = @getDOMNode()
    console.log "willLeave"
    Velocity(node, 'transition.fadeOut', {complete: done})


Title = React.createFactory(TitleClass)

MainClass = React.createClass
  displayName: "Main"
  getInitialState: ->
    title: 'Main'
  changeTitle: ->
    if @state.title is 'Home'
      @setState {title: 'Main'}
    else
      @setState {title: 'Home'}
  render: ->
    (div {style:{width: '100%', fontSize:'25px', textAlign:'center', marginTop:'20px'}},
      (ReactTransitionGroup {transitionName: 'fade'},
        (Title {changeTitle:@changeTitle, title:@state.title})
      )
    )

Main = React.createFactory(MainClass)

React.render(Main({}), document.body)

So thats it. Pretty self explanatory. This ReactTransitionGroup is still quite a mystery to me. It is my understanding that any of its children should get calls to componentWillEnter and componentWillLeave but that doesn't end up happening. According to the docs it seems that I should see the console.log "willEnter" but I don't.

I've been hung up on this for hours. Any ideas?

Upvotes: 0

Views: 751

Answers (3)

Chet
Chet

Reputation: 19889

The solution ends up being to use React.addons.TransitionGroup. The CSSTransitionGroup is just a wrapper that does CSS stuff.

The other issue is that to get the animation callbacks, the children must have a key!

ReactTransitionGroup = React.createFactory(React.addons.TransitionGroup)

# {clip}

(ReactTransitionGroup {transitionName: 'fade'},
  (Title {changeTitle:@changeTitle, title:@state.title, key:'title'})
)

Upvotes: 0

Sorin
Sorin

Reputation: 61

There are two problems I can see in your code above.

The first one is that you are using React.addons.CSSTransitionGroup instead of React.addons.TransitionGroup.

The second problem is that you are expecting componentWillEnter to get triggered on mount when in fact componentWillAppear is the method being triggered.

Upvotes: 2

misuba
misuba

Reputation: 63

CSSTransitionGroup watches for actual uses of the CSS transition property written onto the elements. I'm not sure exactly how, but it sounds like Velocity isn't doing its work in a way that CSSTransitionGroup is twigging to. You may have to call componentWillEnter and componentWillLeave manually. In this situation, it doesn't sound like that'll be hard.

EDIT: oops, I missed that you don't have key attributes on your child components in the group. From what I can tell, componentWillEnter and componentWillLeave should get called, irrespective of anything else, if you get keys on those kids.

Upvotes: 0

Related Questions