在useEffect上设置React-Navigation设置导航参数使PanGestureHandler失去响应

时间:2019-08-11 20:43:12

标签: reactjs react-native

我有一个使用React钩子和react-navigation(V3)的功能组件。我通过将一个对象传递给useEffect函数中的navigation.setParams()来设置屏幕的标题。我正在获取所需的输出,但是这导致PanGestureHandler无法响应。

我不确定这里发生了什么。下面是我的代码实现。

    useEffect(() => {
        BackHandler.addEventListener('hardwareBackPress', handleBackPress)
        props.navigation.setParams({
            title: 'Statistics'
        })
        return () => {
            BackHandler.removeEventListener('hardwareBackPress', handleBackPress)
        }
    })

navigation.setParams()函数外部和之前使用useEffect根本没有效果,不知道为什么。只是为了证明这一点,我从useEffect函数中删除了用于设置标题的代码块,然后PanGestureHandler复活了。

1 个答案:

答案 0 :(得分:0)

const FitnessPlayer = props => {
    const [selectedExercise, setSelectedExercise] = useState(null)
    const handleBackPress = () => {
        if (selectedExercise) {
            setSelectedExercise(null)
            return true;
        }
        props.navigation.goBack()
    }

    useEffect(() => {
        BackHandler.addEventListener('hardwareBackPress', handleBackPress)
        props.navigation.setParams({
            title: 'Statistics'
        })
        return () => {
            BackHandler.removeEventListener('hardwareBackPress', handleBackPress)
        }
    }, [selectedExercise])
    const keyExtractor = ({ key }) => `${key}`;
    const undoSelectedExercise = () => { setSelectedExercise(null) }

    const renderExerciseItem = ({ item }) => {
        const onExercisePressed = () => {
            setSelectedExercise(item)
        }
        return (
            <TouchableOpacity
                key={item.key}
                onPress={onExercisePressed}
            >
                <View
                    style={[styles.card, { flexDirection: 'row', justifyContent: 'space-between', borderRadius: 3 }]}
                >
                    <View style={{ flex: 0.2, justifyContent: 'center', alignItems: 'center' }}>
                        <Image
                            style={{ width: 60, height: 60, resizeMode: 'contain' }}
                            source={images[item.url]}
                        />
                    </View>

                    <View style={{ flex: 0.8, justifyContent: 'center', paddingLeft: 10 }}>
                        <Text style={{ fontWeight: '600', fontSize: 15 }}>{item.title}</Text>
                        <Text>
                            {item.description}
                        </Text>
                    </View>
                </View>
            </TouchableOpacity >)
    }
    // Animationblock////////////////////////////
    const state = new Value(-1)
    const dragVX = new Value(0)
    const dragY = new Value(0)
    offsetY = new Value(0);
    const onGestureEvent = event([
        {
            nativeEvent: {
                translationY: dragY,
                velocity: dragVX,
                state: state
            }
        }
    ])
    const clock = new Clock()
    const translateY = cond(
        eq(state, State.ACTIVE),
        add(offsetY, dragY),
        set(offsetY, add(offsetY, dragY)),
    );

    const animatedHeight = interpolate(translateY, {
        inputRange: [0, SCREEN_HEIGHT - 90],
        outputRange: [SCREEN_HEIGHT - Header.HEIGHT, 100],
        extrapolate: Extrapolate.CLAMP
    })

    return (
        <View style={{ flex: 1 }}>
            <FlatList
                style={{ flex: 1 }}
                data={fitnessData}
                renderItem={renderExerciseItem}
                keyExtractor={keyExtractor}
            />
            {selectedExercise ?
                <PanGestureHandler
                    onGestureEvent={onGestureEvent}
                    onHandlerStateChange={onGestureEvent}
                    maxPointers={1}
                >
                    <Animated.View style={[{
                        position: 'absolute', flex: 1, width: WIDTH, height: HEIGHT, backgroundColor: 'orange', justifyContent: 'center', padding: 10,
                    }, { height: animatedHeight }]}>
                        <Animated.Text>Go back</Animated.Text>
                    </Animated.View>
                </PanGestureHandler>

                : null}
        </View>
    )
}

FitnessPlayer.navigationOptions = ({ navigation }) => (
    {
        title: navigation.getParam('title'),
        headerLeft: navigation.getParam('goBackIcon'),
    }
)

export default FitnessPlayer;