react-anime icon indicating copy to clipboard operation
react-anime copied to clipboard

Support mount/unmount of components

Open markhicken opened this issue 8 years ago • 16 comments

This is SOOO much simpler than other react animation tools out there. If it supported mounting and unmounting animations, it would be the best option available IMO. Have you considered adding this feature?

markhicken avatar Dec 29 '16 01:12 markhicken

@nekcih we are currently a small team (2 people) working on several libraries and projects at the moment. This should have been done long ago and I'm terribly sorry that this is not clearly established in the API. This will be coming soon :)

kennetpostigo avatar Dec 29 '16 05:12 kennetpostigo

Awesome! Thx for the reply!

markhicken avatar Dec 29 '16 05:12 markhicken

So, was this actually completed? Just curious because I don't see a related PR.

markhicken avatar Jan 03 '17 16:01 markhicken

Hey @nekcih the docs for this are currently being worked on, as you probably noticed the readme was cleaned up, and the doc page hyperfuse.github.io/react-anime is being updated. More docs coming soon :)

kennetpostigo avatar Jan 03 '17 17:01 kennetpostigo

Awesome! A few of us are anxiously awaiting that update!

markhicken avatar Jan 03 '17 17:01 markhicken

Hey, so has this been implemented?

du5rte avatar Mar 16 '17 11:03 du5rte

Hey @du5rte, Just opened #11 with some of the changes that are going on with React Anime 2.0, unmounting/mounting animations haven't quite been figured out yet though.

The primary issue with mounting is letting anime.js know which components to animate and which not to animate, since children are props, we need to store the previous children and current children somehow.

alaingalvan avatar Mar 16 '17 18:03 alaingalvan

@alaingalvan wild guess at this point but maybe componentWillReceiveProps() or componentWillUpdate(nextProps, nextState) might do the trick, I'm gonna have a play with this and see what I come up with

du5rte avatar Mar 18 '17 13:03 du5rte

componentWillReceiveProps(nextProps) { // compare this.props to nextProps }

markhicken avatar Mar 18 '17 15:03 markhicken

@alaingalvan @nekcih I've tried look into it but the real issue is animating before unmounting, this is a problem a lot of people are having when trying to do perform unmount animations before when unmounting is trigged that component doesn't stick around waiting for the animation to end. But a new lifecycle for react is being suggested we should really emphasise it's important for animations!

facebook/react#9222

du5rte avatar Mar 20 '17 15:03 du5rte

I've tried look into it but the real issue is animating before unmounting, this is a problem a lot of people are having when trying to do perform unmount animations before when unmounting is trigged that component doesn't stick around waiting for the animation to end. But a new lifecycle for react is being suggested we should really emphasise it's important for animations!wild guess at this point but maybe componentWillReceiveProps() or componentWillUpdate(nextProps, nextState) might do the trick, I'm gonna have a play with this and see what I come up with as you probably noticed the readme was cleaned up, and the doc page hyperfuse.github.io/react-anime is being updated. More docs coming soon :)

shockwavemoto avatar May 30 '17 19:05 shockwavemoto

What's the recommended way to create a mount animation and an unmount animation in React currently?

Right now, I have a boolean flag on state for shouldAnimate. If shouldAnimate is true, I render the <Anime> component around my own component. After the first mount, I flip this boolean so that changes to state in the email form don't trigger the animation.

Now I am trying to think about how to do an animation when the user is done with this component view.

Crizzooo avatar Jun 20 '17 16:06 Crizzooo

@Crizzooo The current recommend way is to use react-motion <TransitionMotion />.

If you search the react library issues for animation unmount you're very likely to land on various proposals of componentWillPrepareUnmount which were close and recommend using react-motion.

#6067 componentWillPrepareUnmount

Mount and unmount animations was one of the main motivations for Chenglou to create react-motion here are his Thoughts on Animation

du5rte avatar Jun 22 '17 09:06 du5rte

I just ran across this... https://facebook.github.io/react/docs/animation.html#low-level-api-reacttransitiongroup

I don't have time to mess with it for now but it seems like it would allow us to fix the unmount issue.

markhicken avatar Sep 01 '17 16:09 markhicken

@markhicken Woah, that looks really good!

Been stuck on this roadblock for so long, might finally be able to break it! 👍

alaingalvan avatar Sep 01 '17 19:09 alaingalvan

I noticed recently that the previous time based store work with version 2.0 was causing issues when I changed the state of my component (lodash diffing wasn't working due to the deep comparison) So I went about fixing that in my branch, as I was doing it I thought I might as well give the mounting/unmounting a crack.

Using the react transition groups it was relatively easy to implement.

Here are some of the results so far: https://imgur.com/a/h5yi4

To do this I created a new AnimeTransition Component that you pass in a enter and exit object that defines the anime properties to use

Here's the code for the gif

import React from 'react';
import './App.css';
import { AnimeTransition } from 'react-anime';

const enter = {
  easing: 'easeInOutElastic',
  duration: 500,
  opacity: [0, 1],
  translateX: [-50, 0]
}

const exit = {
  easing: 'easeInOutElastic',
  duration: 500,
  opacity: [1, 0],
  translateX: [0, -50]  
}

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = { items: [], value: "" }
  }
  handleAdd() {
    this.setState({
      items: [
        ...this.state.items,
        this.state.value
      ]
    });
  }
  handleRemove(i) {
    let newItems = this.state.items.slice();
    newItems.splice(i, 1);
    this.setState({ items: newItems });
  }
  handleChange(event) {
    this.setState({value: event.target.value});
  }
  render() {
    return (
      <div className='container'>
        <AnimeTransition enterAnim={enter} exitAnim={exit} className='todo-list'>
          {this.state.items.map((item, i) => (
            <div key={item} className="list-item">
              {`${item} `}
              <button onClick={() => this.handleRemove(i)}>
                &times;
              </button>
            </div>
          ))}
        </AnimeTransition>
        <button onClick={() => this.handleAdd()}>Add Item</button>
        <input type="text" value={this.state.value} onChange={(event) => this.handleChange(event)} />
      </div>
    );
  }
}

export default App;

To me it was easier to have a seperate component because it removed a couple of edge cases that would have occurred by defining the transition in the original Anime component.

I haven't create unit tests yet but I can create a pull request if this is something @alaingalvan wants in the repo

Source can be found in my fork here

mitchemmc avatar Nov 22 '17 07:11 mitchemmc