Draggable AnimatedViews crash simulator
See original GitHub issueWhen running on iOS simulator, draggable AnimatedViews throw an unhandled error. I’ve already tested this in release on testflight, and the draggable modal behaves as expected with no error.
React Native version:
react: 16.8.3 => 16.8.3 react-native: 0.59.8 => 0.59.8
Steps To Reproduce
- Create an AnimatedView and a PanResponder which controls the position of the view
- Try and drag the View.
The View should drag according to the PanResponder, but instead errors out with the following error:
Invariant Violation: [2165,\"RCTView\",{\"top\":0,\"left\":\"<<NaN>>\",\"transform\":[{\"translateY\":40}]}] is not usable as a native method argument\n at invariant
-[RCTCxxBridge handleError:]
__34-[RCTCxxBridge _initializeBridge:]_block_invoke
facebook::react::RCTMessageThread::tryFunc(std::__1::function<void ()> const&)
facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1::operator()() const
decltype(std::__1::forward<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1&>(fp)()) std::__1::__invoke<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1&>(facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1&&&)
void std::__1::__invoke_void_return_wrapper<void>::__call<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1&>(facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1&&&)
std::__1::__function::__func<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1, std::__1::allocator<facebook::react::RCTMessageThread::runOnQueue(std::__1::function<void ()>&&)::$_1>, void ()>::operator()()
std::__1::function<void ()>::operator()() const
invocation function for block in facebook::react::RCTMessageThread::runAsync(std::__1::function<void ()>)
__CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__
__CFRunLoopDoBlocks
__CFRunLoopRun
CFRunLoopRunSpecific
+[RCTCxxBridge runRunLoop]
__NSThread__start__
_pthread_body
_pthread_start
thread_start
You can reproduce it with the following, however, on snack, this does not crash I assume because Expo is a on their own fork?
import { View,
Text,
StyleSheet,
TouchableOpacity,
TouchableHighlight,
PanResponder,
Animated,
Dimensions,
} from 'react-native';
const { height: SCREEN_HEIGHT } = Dimensions.get('window');
const SWIPE_THRESHOLD = SCREEN_HEIGHT * 0.1;
class ConfirmationModal extends Component {
constructor(props) {
super(props);
const modalPosition = new Animated.ValueXY();
const panResponder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderMove: (_event, gesture) => {
if (gesture.dy > 0) {
modalPosition.setValue({ y: gesture.dy });
}
},
onPanResponderRelease: (_event, gesture) => {
if (gesture.dy <= SWIPE_THRESHOLD) {
Animated.spring(modalPosition, {
toValue: {
x: 0,
y: 0,
},
bounciness: 12,
speed: 8,
}).start();
}
if (gesture.dy > SWIPE_THRESHOLD) {
this.props.toggleModal();
}
},
});
this.state = {
panResponder,
modalPosition,
}
}
getModalStyle() {
const { modalPosition } = this.state;
const drag = modalPosition.y.interpolate({
inputRange: [0, SCREEN_HEIGHT],
outputRange: [0, 250],
});
return {
...modalPosition.getLayout(),
transform: [{ translateY: drag }],
};
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity style={{ flex: 4, opacity: 0.2 }} onPress={this.props.toggleModal} activeOpacity={1} />
<Animated.View style={[styles.contentContainer, this.getModalStyle()]}>
<View style={styles.upperContainer}>
<View style={styles.notch} {...this.state.panResponder.panHandlers} />
<View style={styles.topRow}>
</View>
<View style={{ paddingHorizontal: 20, paddingTop: 5 }}>
</View>
<View style={{ paddingTop: 15, paddingHorizontal: 20, }}>
</View>
</View>
<View style={styles.lowerContainer}>
<TouchableOpacity onPress={this.props.toggleModal}>
<Text style={styles.cancelText}>Cancel</Text>
</TouchableOpacity>
<TouchableHighlight>
<View>
<Text style={styles.confirmText}>Confirm</Text>
</View>
</TouchableHighlight>
</View>
</Animated.View>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
contentContainer: {
flex: 3,
backgroundColor: 'rgb(64, 77, 222)',
borderTopLeftRadius: 13,
borderTopRightRadius: 13,
},
upperContainer: {
flex: 3,
},
lowerContainer: {
flex: 1,
backgroundColor: 'rgb(58, 73, 192)',
flexDirection: 'row',
paddingHorizontal: 20,
justifyContent: 'space-between',
alignItems: 'center',
},
notch: {
height: 8,
width: 48,
backgroundColor: 'rgb(161, 182, 255)',
alignSelf: 'center',
marginTop: 5,
borderRadius: 8,
opacity: 0.85,
},
topRow: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingHorizontal: 20,
},
lowerRow: {
backgroundColor: 'rgb(58, 73, 192)',
},
confirmTitle: {
fontFamily: 'SFProText-Medium',
fontSize: 18,
color: 'rgb(146, 166, 249)',
},
confirmBodyText: {
fontFamily: 'SFProText-Semibold',
fontSize: 20,
lineHeight: 28,
letterSpacing: -0.3,
color: 'rgb(199, 210, 255)',
},
confirmButton: {
paddingHorizontal: 30,
paddingVertical: 15,
borderRadius: 25,
justifyContent: 'center',
alignItems: 'center',
},
cancelText: {
fontFamily: 'SFProText-Medium',
fontSize: 18,
letterSpacing: 0.18,
color: 'rgb(146, 166, 249)',
},
confirmText: {
fontFamily: 'SFProText-Bold',
fontSize: 18,
letterSpacing: -0.6,
color: 'rgb(26, 71, 114)',
},
})
export default ConfirmationModal;
As I said, this is not occurring in our release builds, but obviously makes debugging a pain .
Issue Analytics
- State:
- Created 4 years ago
- Reactions:3
- Comments:8
@steventilator Correct, if you follow down to the Animated API level, you’ll see that
x
is evaluated asNaN
if not suppliedAs a temporary workaround, when setting the modal position using an AnimatedValue with setValue, you must supply an
x
andy
coordinates (lucky for me, my use case does not need anything but 0 as x).By using this
This fixes the issue on simulator. As a side note, the offending underlying API piece is essentially being passed
NaN
as a value, causing the error. Not sure what changes (or when) as we updated from 57 to 59. If I end up with free time I may dig into seeing when this changed (and maybe a contributor can tell us if the change is intended)