You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

useDrawerProgress报错未找到抽屉导航器的动画实现方案

报错现象

运行项目时触发如下报错:

Error: Couldn't find a drawer. Is your component inside a drawer navigator?
错误说明:无法找到抽屉导航实例,请确认当前组件是否嵌套在抽屉导航器(drawer navigator)内部。

关联代码
interface MainContainerProps {
    header?: ToolbarProps,
    props?: any,
    children?: ReactNode
}

const MainContainer: React.FC<MainContainerProps> = ({ header, props, children }) => {
    const [slideDrawer, setSlideDrawer] = useState(false);

    const drawerProgress = useDrawerProgress()

    const screenStyle = useAnimatedStyle(() => {
        const scaleY = interpolate(/*sv.value*/drawerProgress.value, [0, 1], [1, 0.8], {
            extrapolateRight: Extrapolate.CLAMP,
        });

        const borderRadius = interpolate(/*sv.value*/drawerProgress.value, [0, 1], [1, 20], {
            extrapolateRight: Extrapolate.CLAMP,
        });

        const animatedStyle = { borderRadius, transform: [{ scaleY }] };
        console.log('HERE CALLED : ' + scaleY);
        return {
            transform: [
                {
                    scaleY,
                },
            ],
        };
    });

    return (<Animated.View> 
...
</Animated.View>)
需求说明

需要在作为主容器的<Animated.View>中实现抽屉联动动画,当前在MainContainer组件内调用useDrawerProgress()钩子触发上述报错,所有被该MainContainer包裹的页面均受影响,需要找到正确的调整方案,为这些页面正确应用抽屉关联动画效果。

报错原因

useDrawerProgress钩子只能在Drawer.Navigator直接注册的屏幕组件上下文内调用。当前MainContainer是抽离的公共容器组件,本身不属于抽屉导航直接挂载的屏幕,无法获取抽屉导航的上下文实例,因此触发报错。

解决方案

提供两种可落地的调整方式,根据项目场景选择即可:

  • 方式一:通过Props透传抽屉进度值
    不在MainContainer内部直接调用useDrawerProgress,改为在每个被抽屉导航直接注册的页面中调用该钩子拿到进度值,再通过Props传入MainContainer,容器内部直接使用传入的进度值计算动画样式即可。
    抽屉页面调用示例:
    import { useDrawerProgress } from '@react-navigation/drawer';
    
    // 该组件为Drawer.Screen直接注册的页面组件
    const HomePage = () => {
      // 此处可正常获取抽屉进度
      const drawerProgress = useDrawerProgress();
      return (
        <MainContainer drawerProgress={drawerProgress}>
          {/* 页面业务内容 */}
        </MainContainer>
      )
    }
    
    对应修改MainContainer的Props类型定义,新增drawerProgress入参,删除组件内部直接调用useDrawerProgress()的代码即可。
  • 方式二:全局配置抽屉屏幕动画包裹层(推荐)
    如果需要给所有抽屉下的页面统一加联动动画,不想逐个页面修改传值,可以在配置抽屉导航时,统一给屏幕套一层动画容器,该容器处于抽屉导航上下文内,可以正常调用useDrawerProgress,一次配置全局生效。
    配置示例:
    import { createDrawerNavigator, useDrawerProgress } from '@react-navigation/drawer';
    import Animated, { interpolate, Extrapolate, useAnimatedStyle } from 'react-native-reanimated';
    
    const Drawer = createDrawerNavigator();
    
    // 全局抽屉动画包裹组件
    const DrawerAnimatedWrapper = ({ children }) => {
      const drawerProgress = useDrawerProgress();
      const animatedStyle = useAnimatedStyle(() => {
        const scaleY = interpolate(drawerProgress.value, [0, 1], [1, 0.8], {
          extrapolateRight: Extrapolate.CLAMP,
        });
        const borderRadius = interpolate(drawerProgress.value, [0, 1], [1, 20], {
          extrapolateRight: Extrapolate.CLAMP,
        });
        return {
          borderRadius,
          transform: [{ scaleY }]
        }
      });
    
      return <Animated.View style={[{ flex: 1, overflow: 'hidden' }, animatedStyle]}>{children}</Animated.View>
    }
    
    // 根导航配置
    const RootDrawerNavigator = () => {
      return (
        <Drawer.Navigator
          screenOptions={{
            sceneContainerStyle: { backgroundColor: 'transparent' },
          }}
        >
          <Drawer.Screen name="Home" component={HomePage} />
          <Drawer.Screen name="Profile" component={ProfilePage} />
          {/* 其余抽屉页面 */}
        </Drawer.Navigator>
      )
    }
    
    配置完成后,MainContainer不需要再处理抽屉进度相关逻辑,所有页面自动应用抽屉联动动画,后续维护成本更低。

内容的提问来源于stack exchange,提问作者Moin Maniar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 14:18:28