jeecgboot/JeecgBoot · error
useDrawerInner() can only be used inside setup() or…
Error message
useDrawerInner() can only be used inside setup() or functional components!
What it means
useDrawerInner is the inner-side hook used by the component rendered inside a Drawer (it receives data transferred from the opener and accesses the drawer instance). It captures getCurrentInstance() into a variable and also re-checks it in the guard. Like useDrawer, it requires a setup context because it registers lifecycle cleanup. The double getCurrentInstance() call is redundant but harmless. It throws the same class of message when no instance is present.
Solutions
- Call useDrawerInner() at the top of the inner component's <script setup>.
- Ensure the inner drawer content is defined as a proper Vue component (defineComponent or <script setup>).
- Do not call useDrawerInner from the parent/opener component — it belongs only in the inner view.
- If using a callback function parameter, ensure it does not itself call the hook; pass it as an argument instead.
Example fix
// before — inner logic placed in a helper file
// drawerHelper.ts
export function setupDrawer() {
const [register] = useDrawerInner(cb); // throws
}
// after — move into the actual inner .vue component
// InnerDrawer.vue <script setup>
const [register] = useDrawerInner((data) => { /* ... */ }); Defensive patterns
Strategy: validation
Validate before calling
import { getCurrentInstance } from 'vue';
function safeUseDrawerInner(cb?: Fn) {
if (!getCurrentInstance()) {
console.error('useDrawerInner must be called inside the inner drawer component setup');
return null;
}
return useDrawerInner(cb);
} Type guard
import { getCurrentInstance } from 'vue';
const canUseLifecycle = () => !!getCurrentInstance(); Try / catch
try {
const [register] = useDrawerInner(cb);
} catch (e) {
// move the call into the inner .vue component's setup
} Prevention
- Reserve useDrawerInner for the component rendered inside the Drawer only.
- Ensure inner content is a real defineComponent/<script setup>.
- Do not forward the callback into a detached async context.
When it happens
Trigger: Calling useDrawerInner() in a non-component module, a Pinia store, a composable invoked outside setup, or any detached async context. Because the inner component is usually a child route/view, a common trigger is the child view failing to be a real Vue component (e.g. a plain function returning JSX without defineComponent).
Common situations: Refactoring the inner drawer view into a separate file but calling the hook in a utility; using useDrawerInner inside a render function without a proper component definition; calling it during SSR where instance availability differs.
Related errors
- useDrawer() can only be used inside setup() or functional…
- useDescription() can only be used inside setup() or…
- useModal() can only be used inside setup() or functional…
- useTableContext must be used after createTableContext
- 提交任务失败
AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14).
Data as JSON: /api/errors/c16c32ffbeaff3b1.
Report an issue: GitHub.
Appendix: source
Thrown at jeecgboot-vue3/src/components/Drawer/src/useDrawer.ts:97
dataTransferRef[unref(uid)] = toRaw(data);
}
},
closeDrawer: () => {
// 代码逻辑说明: 【QQYUN-6366】升级到antd4.x
getInstance()?.setDrawerProps({ open: false });
},
};
return [register, methods];
}
export const useDrawerInner = (callbackFn?: Fn): UseDrawerInnerReturnType => {
const drawerInstanceRef = ref<Nullable<DrawerInstance>>(null);
const currentInstance = getCurrentInstance();
const uidRef = ref<string>('');
if (!getCurrentInstance()) {
throw new Error('useDrawerInner() can only be used inside setup() or functional components!');
}
const getInstance = () => {
const instance = unref(drawerInstanceRef);
if (!instance) {
error('useDrawerInner instance is undefined!');
return;
}
return instance;
};
const register = (modalInstance: DrawerInstance, uuid: string) => {
isProdMode() &&
tryOnUnmounted(() => {
drawerInstanceRef.value = null;
});
uidRef.value = uuid;View on GitHub (pinned to 96fb33f5ec)