1

我正在使用react-native-popup-menu并创建了我自己的renderer组件。它是一个函数组件,所以简而言之它看起来像这样:

const ContextMenuRenderer = ({ children, layouts, ...otherProps }) => {
  return (
    <Animated.View
      {...otherProps}
      onLayout={handleViewLayout}
      style={[styles.viewStyle, viewAnimations]}
    >
      {children}
    </Animated.View>
  );
}

viewAnimations包含开场动画,代码比较大,但可以在这个小吃中看到。

文档说“为了处理异步关闭动画,渲染器可以实现close()在菜单关闭之前调用的方法。关闭方法必须返回Promise。”

我阅读了ContextMenu 代码,它是一个类组件并实现close()为:

close() {
  return new Promise(resolve => {
    Animated.timing(this.state.scaleAnim, {
      duration: CLOSE_ANIM_DURATION,
      toValue: 0,
      easing: Easing.in(Easing.cubic),
      useNativeDriver: USE_NATIVE_DRIVER,
    }).start(resolve);
  });
}

我试图在我的函数组件中实现类似的东西,但代码没有被执行。我认为它不起作用,但我能做些什么来创建关闭动画?我想做一个淡出动画。

function close() {
  console.log('close'); // It isn't logged
  return new Promise((resolve) => {
    console.log('resolve close');
  });
}
4

1 回答 1

1

为了让你的渲染器开始关闭动画,RN popup 方法close通过 ref 调用命令式方法。

最安全的方法(就它也被库使用和证明而言)是为此使用类组件(正如您已经发现的那样)。

另一种选择可能是将钩子 useImperativeHandle 与 forwardRef 一起使用。就像是

function FancyRenderer(props, ref) {
  useImperativeHandle(ref, () => ({
    close: () => {
      return new Promise(...);
    }
  }));
  return <View>;
}
FancyRenderer = forwardRef(FancyRenderer);

我记得我们正在尝试以某种方式检查我们是否可以ref首先获得,所以我不确定你是否会按照钩子之前的编码工作,我们从未尝试过这种方式。在这种情况下,可能需要小的 PR。

于 2020-07-18T12:58:20.830 回答