Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support mount/unmount of components #10

Open
markhicken opened this issue Dec 29, 2016 · 16 comments
Open

Support mount/unmount of components #10

markhicken opened this issue Dec 29, 2016 · 16 comments
Assignees

Comments

@markhicken
Copy link

markhicken commented Dec 29, 2016

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?

@kennetpostigo
Copy link
Member

@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 :)

@markhicken
Copy link
Author

Awesome! Thx for the reply!

@markhicken
Copy link
Author

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

@kennetpostigo
Copy link
Member

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 :)

@alaingalvan alaingalvan reopened this Jan 3, 2017
@markhicken
Copy link
Author

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

@du5rte
Copy link

du5rte commented Mar 16, 2017

Hey, so has this been implemented?

@alaingalvan
Copy link
Member

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.

@du5rte
Copy link

du5rte commented Mar 18, 2017

@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

@markhicken
Copy link
Author

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

@du5rte
Copy link

du5rte commented Mar 20, 2017

@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

@shockwavemoto
Copy link

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 :)

@Crizzooo
Copy link

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 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.

@du5rte
Copy link

du5rte commented Jun 22, 2017

@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

@markhicken
Copy link
Author

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.

@alaingalvan
Copy link
Member

@markhicken Woah, that looks really good!

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

@alaingalvan alaingalvan self-assigned this Nov 1, 2017
@mitchemmc
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants