{"record":{"id":"47dd4dc098de8cca","repo":"jeecgboot/JeecgBoot","slug":"usedescription-can-only-be-used-inside-setup-o","errorCode":null,"errorMessage":"useDescription() can only be used inside setup() or functional components!","messagePattern":"useDescription\\(\\) can only be used inside setup\\(\\) or functional components!","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"jeecgboot-vue3/src/components/Description/src/useDescription.ts","lineNumber":7,"sourceCode":"import type { DescriptionProps, DescInstance, UseDescReturnType } from './typing';\nimport { ref, getCurrentInstance, unref, onUnmounted } from 'vue';\nimport { isProdMode } from '/@/utils/env';\n\nexport function useDescription(props?: Partial<DescriptionProps>): UseDescReturnType {\n  if (!getCurrentInstance()) {\n    throw new Error('useDescription() can only be used inside setup() or functional components!');\n  }\n  const desc = ref<Nullable<DescInstance>>(null);\n  const loaded = ref(false);\n\n  function register(instance: DescInstance) {\n    // update-begin--author:liaozhiyang---date:20251223---for:【pull/9125】在抽屉中配置destroy-on-close，再次打开未正确渲染\n    isProdMode() &&\n      onUnmounted(() => {\n        desc.value = null;\n        loaded.value = false;\n      });\n    if (unref(loaded) && isProdMode() && instance === unref(desc)) return;\n    // update-end--author:liaozhiyang---date:20251223---for:【pull/9125】在抽屉中配置destroy-on-close，再次打开未正确渲染\n    desc.value = instance;\n    props && instance.setDescProps(props);\n    loaded.value = true;\n  }\n","sourceCodeStart":1,"sourceCodeEnd":25,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecgboot-vue3/src/components/Description/src/useDescription.ts#L1-L25","documentation":"useDescription is a Vue 3 composition-API hook that pairs a Description component with its controller via a register/callback pattern. Like all such hooks, it requires an active component instance to register lifecycle hooks (onUnmounted). It guards by checking getCurrentInstance() at call time — if null, the hook is being invoked outside of setup() and lifecycle registration would silently fail, so it throws immediately rather than producing a broken ref.","triggerScenarios":"Calling useDescription() at module top-level, inside a plain function (not a Vue setup context), inside an async callback resolved after setup returns, inside a setTimeout/setInterval handler, or inside a Pinia store action. Also triggered by calling it inside <script setup> but in a top-level await continuation that detaches from the instance context.","commonSituations":"Refactoring that moves the hook call out of setup; extracting logic into a composable that forgets to forward the setup context; calling openDescription inside an event handler defined outside setup; SSR or testing utilities that mount components without a proper instance.","solutions":["Move the useDescription() call to the top level of <script setup> or the setup() function body.","If extracting into a composable, ensure the composable itself is called synchronously from setup and calls useDescription synchronously.","Avoid wrapping the call in async/await at the top level — call it first, then await.","If you genuinely need to trigger actions outside setup, use the returned methods object (openModal-style) rather than calling the hook again."],"exampleFix":"// before — called in an async callback\nonMounted(async () => {\n  const [register, desc] = useDescription(); // throws\n});\n\n// after — call synchronously at setup top level\nconst [register, desc] = useDescription();\nonMounted(async () => { /* use desc */ });","handlingStrategy":"validation","validationCode":"// Guard the hook call so misuse fails with a clear message in dev\nimport { getCurrentInstance } from 'vue';\nfunction safeUseDescription(props?: Partial<DescriptionProps>) {\n  if (!getCurrentInstance()) {\n    console.warn('useDescription called outside setup — skipping');\n    return null;\n  }\n  return useDescription(props);\n}","typeGuard":"import { getCurrentInstance } from 'vue';\nfunction isInSetup(): boolean {\n  return !!getCurrentInstance();\n}","tryCatchPattern":"// If you must call conditionally\nlet desc;\ntry {\n  desc = useDescription();\n} catch (e) {\n  // handle missing setup context gracefully\n}","preventionTips":["Always call composition hooks at the top of <script setup>, synchronously.","Never place hook calls inside async callbacks or setTimeout.","When extracting composables, ensure they run within setup and call hooks synchronously."],"tags":["vue3","composition-api","setup","lifecycle","frontend"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}