调用外部函数时,GestureDetector 手势处理程序应用程序崩溃

Mic*_*aël 3 react-native fling react-native-gesture-handler

我尝试GestureDetector使用react-native-gesture-handler

import React from 'react';
import { Directions, Gesture, GestureDetector } from 'react-native-gesture-handler';
import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';

/**
 * Component used as Home Page
 */
const HomePage: React.FC  = () => {
  const position = useSharedValue(0);
  const trigger = () => {
    console.log('fdfs')
  }

  const flingGesture = Gesture.Fling()
    .direction(Directions.RIGHT)
    .onStart((e) => {
      position.value = withTiming(position.value + 10, { duration: 100 });
      console.log(e)
      // trigger()
    });

    const flingGestureLeft = Gesture.Fling()
    .direction(Directions.LEFT)
    .onStart((e) => {
      position.value = withTiming(position.value - 10, { duration: 100 });
      // trigger()
    });

  const animatedStyle = useAnimatedStyle(() => ({
    transform: [{ translateX: position.value }],
  }));

  return (
    <GestureDetector gesture={Gesture.Simultaneous(flingGestureLeft, flingGesture)}>
      <Animated.View style={[{ width: 100, height: 30, backgroundColor: 'red' }, animatedStyle]} />
    </GestureDetector>
  );
}

export default HomePage;
Run Code Online (Sandbox Code Playgroud)

当我将块向左或向右滑动时,这项工作没有问题,但是当我尝试调用像 之类的外部函数时trigger(),我的应用程序崩溃了。手势检测器有错误还是需要添加一些内容?

小智 5

重新启动的手势处理程序挂钩和回调在 UI 线程上工作,而您定义的触发函数默认在 JS 线程上,因此您不能直接使用它。

对此有两种解决方案:

  1. 在触发函数中添加“ worklet ”,如下所示
    const trigger = () => {
      'worklet'
      console.log('fdfs')
    }
Run Code Online (Sandbox Code Playgroud)
  1. 或者用 ' runOnJS ' 来包装你的函数,如下所示

    import { runOnJS } from 'react-native-reanimated';

    const flingGesture = Gesture.Fling()
      .direction(Directions.RIGHT)
      .onStart((e) => {
        position.value = withTiming(position.value + 10, { duration: 100 });
        console.log(e)
        runOnJS(trigger)()
      });

Run Code Online (Sandbox Code Playgroud)

注意:runOnJS 的语法类似于“runOnJS(functionName)(params)”。因此,如果您的函数需要两个参数(例如第一个数字和第二个字符串),您可以这样调用它:- runOnJS(trigger)(1, 'dummyString')

有关更多详细信息,您可以阅读reanimatedgesture-handler的文档。