-
Notifications
You must be signed in to change notification settings - Fork 47.2k
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
Proposal: componentWillPrepareUnmount (continueCallback) #6067
Comments
At first glance, that actually seems pretty clever! cc @sebmarkbage @vjeux |
This is essentially what transition group is about. Except that one doesn't allow an abstraction in the child hierarchy to be in control over the animation. Consequently you want something like this. However, if you do this, then the parent of this and the parent of that will have to be aware at some stage that this thing is still alive so that it doesn't delete it from its set. That's what "completion propagation" as mentioned here: #2928 is all about. To make this work we would also need some kind of completion propagation so that a parent can know when a child is supposed to remain undeleted and when it is safe to remove it from the parent. Also, what happens if the same key gets restored while this is still happening? Are components above it? E.g. is a parent of this allowed to update its state while this is happening? While something like this API is certainly something we need, it has a few dependent complexities to make that work. |
@sebmarkbage Good point about restoration. I'm thinking that it should be safe to assume a re-attached component can cancel the ongoing unmount preparation (by ignoring the continueCallback when it's called) and do one of the following:
|
Probably the component also needs to know if the removal was interrupted, so that it can animate back to previous state. |
@satya164 @sebmarkbage I amended the proposal with |
Isn't this essentially: <MyList>
<MyAnimatedChild
key={...}
onRemoveAnimationComplete={this.handleDeleteChild...}
isRemoving={this.isRemoving[...]}
/>
...
</MyList> From this you can deduce (*) Because the parents needs to keep track of children being removed and also keep rendering them somehow, this cannot be handled transparently in the generic case. One can also provide an abstraction for simplifying dealing with (or even hiding) |
@syranide It's true you can achieve the same result in other ways. Another great way is to use the ReactTransitionGroup addon, but with both that and your solution some wrapping logic is required. The idea of my proposition is to be able to perform an unmount transition solely using the component and no wrapping. Also, can you explain why this cannot be handled transparently in the generic case? |
A parent cannot simply stop rendering a child and still have the child remain rendered (and animating), at the very least the child has to be ordered among the other children and without the child being actively rendered that information is simply not available to React. Consider three children, So unless I'm missing something, your proposal requires the same EDIT:
My solution does not require wrapping logic, it requires having the child extend a different base class or apply a mixin unless you want to reimplement the shared logic every time. |
@chenglou thought about this a lot (which resulted in react-motion). I found his thoughts on animation quite insightful. |
After some discussions with Sebastian, and thinking on this issue, I agree that this doesn't elegantly handle the edge cases for the reasons mentioned above (classic problem with proposed solutions to animation). For this reason, I'm going to close out the issue. But feel free to continue the discussion on this thread, and we can re-open if our thinking changes dramatically. |
EDIT: After discussion in this thread I've amended
componentWillRemount
to the proposal.I've been working a lot with animations in combination with react lately and while most lifecycle methods make transitions on components a walk in the park, I've struggled to get the scenario of unmounting a pleasant experience. In the end though I've come up with a lifecycle method proposal that could be incredibly powerful:
componentWillPrepareUnmount (continueCallback)
andcomponentWillRemount
.What they would do, when declared on a component, is to delay the actual unmount just as if nothing happened, until the component itself calls the provided callback, which then would resume the actual unmounting. If a component in a pending unmount state is restored before the actual unmount takes place, the unmount is canceled and the component treats the change as a regular update (
componentWillUpdate
fires, etc), with the addition ofcomponentWillRemount
being called to give you the chance to react specifically to this event.This would allow us to gracefully perform an animation on our components right before they're really unmounted, letting component specific code decide how it should disappear.
For example:
And the usage:
What do you think?
The text was updated successfully, but these errors were encountered: