{"record":{"id":"d6b1489f19ad2767","repo":"jeecgboot/JeecgBoot","slug":"usetablecontext-must-be-used-after-createtablecont","errorCode":null,"errorMessage":"useTableContext must be used after createTableContext","messagePattern":"useTableContext must be used after createTableContext","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"jeecgboot-vue3/src/components/Table/src/hooks/useTableContext.ts","lineNumber":30,"sourceCode":"};\n\ntype RetInstance = Omit<Instance, 'getBindValues'> & {\n  getBindValues: ComputedRef<BasicTableProps>;\n};\n\nexport function createTableContext(instance: Instance) {\n  // 每次创建 context 时都生成新的唯一 Symbol\n  const key = Symbol(`basic-table-${++tableIdCounter}`);\n  provide(key, instance);\n  // 同时提供一个内部标记，让子组件能获取到这个 key\n  provide('__BASIC_TABLE_CONTEXT_KEY__', key);\n}\n\nexport function useTableContext(): RetInstance {\n  // 从最近的父组件获取 context key\n  const key = inject<symbol>('__BASIC_TABLE_CONTEXT_KEY__');\n  if (!key) {\n    throw new Error('useTableContext must be used after createTableContext');\n  }\n  return inject(key) as RetInstance;\n}\n","sourceCodeStart":12,"sourceCodeEnd":34,"githubUrl":"https://github.com/jeecgboot/JeecgBoot/blob/96fb33f5ec68516da0b0147da06b2eb0419e063a/jeecgboot-vue3/src/components/Table/src/hooks/useTableContext.ts#L12-L34","documentation":"useTableContext uses Vue's provide/inject with a dynamic Symbol key. The parent table calls createTableContext (which provides a Symbol under '__BASIC_TABLE_CONTEXT_KEY__'), and child cells/features call useTableContext to inject the table instance. If a child invokes useTableContext but no ancestor has called createTableContext, the inject returns undefined and the guard throws. This enforces that context-only features are never used detached from a table.","triggerScenarios":"A JVxeTable cell component or a feature hook (e.g. a toolbar or pagination sub-component) rendered outside of a <JVxeTable> or <BasicTable> wrapper. Also triggered when a cell is rendered in a preview/storybook environment without the table provider, or when the table's createTableContext is conditionally skipped.","commonSituations":"Reusing a table cell component in a standalone form or grid; rendering table sub-components in isolation for testing; refactoring that moves a cell outside the table slot; conditional rendering that skips the table wrapper but still renders children.","solutions":["Ensure the component calling useTableContext is always a descendant of a BasicTable/JVxeTable that calls createTableContext.","In tests/stories, wrap the component in a minimal table or mock the provide('__BASIC_TABLE_CONTEXT_KEY__') call.","Add a v-if guard so the child only renders when inside a table (pass an `inTable` prop).","If you need table-like features standalone, refactor to pass the instance via props instead of inject."],"exampleFix":"// before — cell used outside a table\n<MyCustomCell />  <!-- calls useTableContext, throws -->\n\n// after — wrap in a table provider, or guard\n<BasicTable>\n  <MyCustomCell />\n</BasicTable>","handlingStrategy":"type-guard","validationCode":"// Check inject availability before using context\nimport { inject } from 'vue';\nfunction useTableContextOrNull() {\n  const key = inject<symbol>('__BASIC_TABLE_CONTEXT_KEY__');\n  if (!key) return null;\n  return inject(key);\n}","typeGuard":"import { inject } from 'vue';\nfunction isInsideTable(): boolean {\n  return !!inject<symbol>('__BASIC_TABLE_CONTEXT_KEY__');\n}","tryCatchPattern":"try {\n  const ctx = useTableContext();\n} catch (e) {\n  // not inside a table; render a fallback or skip\n}","preventionTips":["Only render context-dependent children as descendants of the table provider.","In stories/tests, wrap cells in a table or mock the provide call.","Add an inTable prop to opt into context usage."],"tags":["vue3","provide-inject","table","composition-api","frontend"],"backgroundTag":null,"analyzedSha":"96fb33f5ec68516da0b0147da06b2eb0419e063a","analyzedAt":"2026-08-14T00:04:16.786Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}