jeecgboot/JeecgBoot · error
useDrawer() can only be used inside setup() or functional co
Error message
useDrawer() can only be used inside setup() or functional components!
What it means
useDrawer is the controller-side hook for the Drawer component pair (useDrawer/useDrawerInner). It creates a ref to hold the drawer instance and registers tryOnUnmounted cleanup for the data-transfer map and visible-state tracking. Because the cleanup and the uid ref rely on an active component instance, the hook guards with getCurrentInstance() and throws if invoked outside a setup context. This mirrors the pattern used by useModal and useDescription.
Source
Thrown at jeecgboot-vue3/src/components/Drawer/src/useDrawer.ts:18
import type { UseDrawerReturnType, DrawerInstance, ReturnMethods, DrawerProps, UseDrawerInnerReturnType } from './typing';
import { ref, getCurrentInstance, unref, reactive, watchEffect, nextTick, toRaw, computed } from 'vue';
import { isProdMode } from '/@/utils/env';
import { isFunction } from '/@/utils/is';
import { tryOnUnmounted } from '@vueuse/core';
import { isEqual } from 'lodash-es';
import { error } from '/@/utils/log';
const dataTransferRef = reactive<any>({});
const visibleData = reactive<{ [key: number]: boolean }>({});
/**
* @description: Applicable to separate drawer and call outside
*/
export function useDrawer(): UseDrawerReturnType {
if (!getCurrentInstance()) {
throw new Error('useDrawer() can only be used inside setup() or functional components!');
}
const drawer = ref<DrawerInstance | null>(null);
const loaded = ref<Nullable<boolean>>(false);
const uid = ref<string>('');
function register(drawerInstance: DrawerInstance, uuid: string) {
isProdMode() &&
tryOnUnmounted(() => {
drawer.value = null;
loaded.value = null;
dataTransferRef[unref(uid)] = null;
});
if (unref(loaded) && isProdMode() && drawerInstance === unref(drawer)) {
return;
}
uid.value = uuid;
drawer.value = drawerInstance;View on GitHub (pinned to 96fb33f5ec)
Solutions
- Call useDrawer() synchronously at the top of <script setup> or setup().
- If you need to control the drawer from outside setup, keep the hook call in setup and expose/return the methods to wherever they are needed.
- Ensure the component using useDrawer is actually rendered within a Vue component tree (not a standalone function).
- For shared cross-component drawer control, use a Pinia store that holds the methods reference rather than calling the hook repeatedly.
Example fix
// before — hook called in a store action
actions: {
openDrawer() {
const [register, methods] = useDrawer(); // throws
}
}
// after — call in component setup, delegate to store
// MyPage.vue
const [register, methods] = useDrawer();
drawerStore.setMethods(methods); Defensive patterns
Strategy: validation
Validate before calling
import { getCurrentInstance } from 'vue';
function safeUseDrawer() {
if (!getCurrentInstance()) {
throw new Error('useDrawer must be called in setup(); move the call into <script setup>');
}
return useDrawer();
} Type guard
import { getCurrentInstance } from 'vue';
const isInsideComponent = () => getCurrentInstance() !== null; Try / catch
try {
const [register, methods] = useDrawer();
} catch (e) {
// recover by deferring drawer control to a store set in setup
} Prevention
- Keep useDrawer() calls in <script setup> only.
- For cross-component control, store the returned methods in Pinia rather than re-calling the hook.
- Lint for hook calls outside .vue files.
When it happens
Trigger: Calling useDrawer() inside a non-setup function, a Pinia store, a utility module, a router guard, or any async continuation that has lost the component instance. Also triggered when the hook is imported and invoked in a plain .ts file rather than a .vue component.
Common situations: Moving drawer-control logic into a shared composable or store; calling openDrawer from a global event bus handler; refactoring that splits the register call from setup; testing the hook in isolation without a Vue instance.
Related errors
- useDrawerInner() can only be used inside setup() or function
- useDescription() can only be used inside setup() or function
- useModal() can only be used inside setup() or functional com
- useTableContext must be used after createTableContext
- 提交任务失败
AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14).
Data as JSON: /api/errors/c6024e69b91f6115.
Report an issue: GitHub.