I have an element controlling the rendering of a child element. (A TouchableHighlight that sets some state in its onPress
.) In the child element's componentDidMount
method I construct an Animated.spring
and start
it. This works for entry, but I need to do the same animation in reverse to exit (it's like a drawer). componentWillUnmount
executes too quickly for Animated.spring
to even start working.
How would I handle animating the child's exit?
I have implemented a FadeInOut
component that will animate a component in or out when its isVisible
property changes. I made it because I wanted to avoid explicitly handling the visibility state in the components that should enter/exit with an animation.
<FadeInOut isVisible={this.state.someBooleanProperty} style={styles.someStyle}>
<Text>Something...</Text>
</FadeInOut>
This implementation uses a delayed fade, because I use it for showing progress indicator, but you can change it to use any animation you want, or generalise it to accept the animation parameters as props:
'use strict';
import React from 'react-native';
const {
View,
Animated,
PropTypes
} = React;
export default React.createClass({
displayName: 'FadeInOut',
propTypes: {
isVisible: PropTypes.bool.isRequired,
children: PropTypes.node.isRequired,
style: View.propTypes.style
},
getInitialState() {
return {
view: this.props.children,
opacity: new Animated.Value(this.props.isVisible ? 1 : 0)
};
},
componentWillReceiveProps(nextProps) {
const isVisible = this.props.isVisible;
const shouldBeVisible = nextProps.isVisible;
if (isVisible && !shouldBeVisible) {
Animated.timing(this.state.opacity, {
toValue: 0,
delay: 500,
duration: 200
}).start(this.removeView);
}
if (!isVisible && shouldBeVisible) {
this.insertView();
Animated.timing(this.state.opacity, {
toValue: 1,
delay: 500,
duration: 200
}).start();
}
},
insertView() {
this.setState({
view: this.props.children
});
},
removeView() {
this.setState({
view: null
});
},
render() {
return (
<Animated.View
pointerEvents={this.props.isVisible ? 'auto' : 'none'}
style={[this.props.style, {opacity: this.state.opacity}]}>
{this.state.view}
</Animated.View>
);
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With