为什么两个独立的组件在 React Native 中共享状态?
Why are two separate components sharing state in React Native?
我正在尝试实现多点触控滑块功能(基于 React Native Gesture Handler 提供的示例代码)。
我发现当我创建两个 TapOrPan
组件时,它们可以单独工作,但当同时触摸 两个 滑块时,滑块状态是共享的。
鉴于我使用的是两个独立的组件,为什么会发生这种情况?我错过了什么?
Expo link 用于调试:https://snack.expo.io/aPLAoFWar
import React, { Component } from 'react';
import { Animated, Dimensions, StyleSheet, Text, View } from 'react-native';
import {
PanGestureHandler,
TapGestureHandler,
ScrollView,
State,
} from 'react-native-gesture-handler';
export function TapOrPan({width, radius}) {
const tapRef = React.createRef();
const panRef = React.createRef();
const _id = parseInt(Math.random() * 100);
const _touchX = new Animated.Value(width / 2 - radius);
const _circleValue = new Animated.Value(-radius);
const _translateX = Animated.add(_touchX, _circleValue);
const _onPanGestureEvent = Animated.event(
[{nativeEvent: {x: _touchX}}],
{useNativeDriver: true}
);
const styles = StyleSheet.create({
horizontalPan: {
backgroundColor: '#777',
height: 120,
justifyContent: 'center',
marginVertical: 10,
},
circle: {
backgroundColor: '#fff',
borderRadius: radius,
height: radius * 2,
width: radius * 2,
},
wrapper: {
flex: 1,
},
});
function _onTapHandlerStateChange({ nativeEvent }) {
console.log(_id.toString() + ": " + JSON.stringify(nativeEvent));
if (nativeEvent.oldState === State.ACTIVE) {
// Once tap happened we set the position of the circle under the tapped spot
_touchX.setValue(nativeEvent.x);
}
}
return (
<TapGestureHandler
ref={tapRef}
onHandlerStateChange={_onTapHandlerStateChange}
>
<Animated.View style={styles.wrapper}>
<PanGestureHandler
ref={panRef}
activeOffsetX={[0, 0]}
onGestureEvent={_onPanGestureEvent}
>
<Animated.View style={styles.horizontalPan}>
<Animated.View
style={[
styles.circle,
{transform: [{translateX: _translateX}]},
]}
/>
</Animated.View>
</PanGestureHandler>
</Animated.View>
</TapGestureHandler>
);
}
export default function Example() {
const windowWidth = Dimensions.get('window').width;
return (
<ScrollView>
<TapOrPan width={windowWidth} radius={30} />
<TapOrPan width={windowWidth} radius={30} />
</ScrollView>
);
}
如果认为它不会如您所愿。两个不同方向移动的手指没有两个坐标。某个点只有一个坐标,它是根据你所有手指的坐标计算出来的
(不同平台不同)。
https://github.com/software-mansion/react-native-gesture-handler/blob/d3c8ff130e7d925dae7cec149098c5d042a00120/android/lib/src/main/java/com/swmansion/gesturehandler/PanGestureHandler.java#L44
我正在尝试实现多点触控滑块功能(基于 React Native Gesture Handler 提供的示例代码)。
我发现当我创建两个 TapOrPan
组件时,它们可以单独工作,但当同时触摸 两个 滑块时,滑块状态是共享的。
鉴于我使用的是两个独立的组件,为什么会发生这种情况?我错过了什么?
Expo link 用于调试:https://snack.expo.io/aPLAoFWar
import React, { Component } from 'react';
import { Animated, Dimensions, StyleSheet, Text, View } from 'react-native';
import {
PanGestureHandler,
TapGestureHandler,
ScrollView,
State,
} from 'react-native-gesture-handler';
export function TapOrPan({width, radius}) {
const tapRef = React.createRef();
const panRef = React.createRef();
const _id = parseInt(Math.random() * 100);
const _touchX = new Animated.Value(width / 2 - radius);
const _circleValue = new Animated.Value(-radius);
const _translateX = Animated.add(_touchX, _circleValue);
const _onPanGestureEvent = Animated.event(
[{nativeEvent: {x: _touchX}}],
{useNativeDriver: true}
);
const styles = StyleSheet.create({
horizontalPan: {
backgroundColor: '#777',
height: 120,
justifyContent: 'center',
marginVertical: 10,
},
circle: {
backgroundColor: '#fff',
borderRadius: radius,
height: radius * 2,
width: radius * 2,
},
wrapper: {
flex: 1,
},
});
function _onTapHandlerStateChange({ nativeEvent }) {
console.log(_id.toString() + ": " + JSON.stringify(nativeEvent));
if (nativeEvent.oldState === State.ACTIVE) {
// Once tap happened we set the position of the circle under the tapped spot
_touchX.setValue(nativeEvent.x);
}
}
return (
<TapGestureHandler
ref={tapRef}
onHandlerStateChange={_onTapHandlerStateChange}
>
<Animated.View style={styles.wrapper}>
<PanGestureHandler
ref={panRef}
activeOffsetX={[0, 0]}
onGestureEvent={_onPanGestureEvent}
>
<Animated.View style={styles.horizontalPan}>
<Animated.View
style={[
styles.circle,
{transform: [{translateX: _translateX}]},
]}
/>
</Animated.View>
</PanGestureHandler>
</Animated.View>
</TapGestureHandler>
);
}
export default function Example() {
const windowWidth = Dimensions.get('window').width;
return (
<ScrollView>
<TapOrPan width={windowWidth} radius={30} />
<TapOrPan width={windowWidth} radius={30} />
</ScrollView>
);
}
如果认为它不会如您所愿。两个不同方向移动的手指没有两个坐标。某个点只有一个坐标,它是根据你所有手指的坐标计算出来的 (不同平台不同)。 https://github.com/software-mansion/react-native-gesture-handler/blob/d3c8ff130e7d925dae7cec149098c5d042a00120/android/lib/src/main/java/com/swmansion/gesturehandler/PanGestureHandler.java#L44