ctxToMultiEnumControlProps omits props.options from its useMemo dependency array, unlike its enum/oneOf-enum siblings: multi enum control never picks up externally-updated options
Nobody has claimed this yet.
Assessment
- Difficulty
- 1/5
- Estimated time
- Under an hour
- Newbie friendliness
- 88/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- react, typescript
- Domain
- frontend
Research direction
Start in packages/react/src/JsonFormsContext.tsx at ctxToMultiEnumControlProps, then compare its useMemo dependencies with ctxToEnumControlProps and ctxToOneOfEnumControlProps. Ensure externally updated options are reflected after an asynchronous own-prop update, without requiring schema or translation changes.
Written by the indexing model from the issue text.
Description
Describe the bug
ctxToMultiEnumControlProps in packages/react/src/JsonFormsContext.tsx (the multi enum variant used internally by withJsonFormsMultiEnumProps) memoizes its options result with a useMemo call that's missing props.options from its dependency array. Its two closest siblings, ctxToEnumControlProps (plain enum control) and ctxToOneOfEnumControlProps (one-of enum control), both correctly include it:
// ctxToEnumControlProps — correct
const options = useMemo(
() => enumProps.options,
[props.options, enumProps.schema, ctx.i18n?.translate]
);
// ctxToOneOfEnumControlProps — correct
const options = useMemo(
() => enumProps.options,
[props.options, enumProps.schema, ctx.i18n?.translate]
);
// ctxToMultiEnumControlProps — missing props.options
const options = useMemo(
() => enumProps.options,
[enumProps.schema, ctx.i18n?.translate]
);
The two "cell" equivalents (ctxToEnumCellProps, ctxToOneOfEnumCellProps) also both correctly include their own-props options dependency, so this looks like an isolated omission on just this one function rather than a deliberate difference.
Impact: any consumer that passes its own options as an own prop into a multi enum control (most notably a custom renderer implementing dynamically-fetched options, composed outside withJsonFormsMultiEnumProps so it can inject options as a prop after an async fetch resolves) never sees that value take effect. The memo computed on the very first render (before the async options arrive) is permanently stuck, because none of the other dependencies (enumProps.schema, ctx.i18n?.translate) change when the options later arrive. The exact same pattern for a single-value enum/one-of-enum control works correctly, since props.options is a dependency there.
Concretely: any multi-select control whose available options are computed or fetched asynchronously and handed to it via options as an own prop will render an empty list forever, until something unrelated happens to also change schema (e.g. editing the field definition, which is why this can look intermittent).
Suggested fix:
export const ctxToMultiEnumControlProps = (
ctx: JsonFormsStateContext,
props: OwnPropsOfControl
) => {
const enumProps = mapStateToMultiEnumControlProps(
{ jsonforms: { ...ctx } },
props
);
const options = useMemo(
() => enumProps.options,
- [enumProps.schema, ctx.i18n?.translate]
- [props.options, enumProps.schema, ctx.i18n?.translate]
);
return { ...enumProps, options };
};
Expected behavior
A multi enum control should pick up an externally-updated options own prop the same way a plain enum control or a one-of-enum control already does, since all three follow the identical pattern and only the multi-enum variant's memo omits the dependency that makes that work.
Steps to reproduce the issue
- Render a control using
withJsonFormsMultiEnumProps, wrapped by a custom HOC that suppliesoptionsas a prop asynchronously (e.g.setTimeout(() => setOptions([...]), 0)before passingoptions={options}down). - Observe that the wrapped component's
optionsprop stays at its initial (empty) value even after the async update, while the identical pattern usingwithJsonFormsOneOfEnumPropscorrectly reflects the update.
Screenshots
No response
Which Version of JSON Forms are you using?
@jsonforms/react@3.9.0-alpha.1
Package
No response
Additional context
No response
- Dominant language
- TypeScript
- Stars
- 2.7k
- Forks
- 423
- Avg merge
- 17d 8h
- Merged PRs (30d)
- 1
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from eclipsesource/jsonforms
-
react
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
eclipsesource/jsonforms#2616 · 1 comment ·
-
core
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
eclipsesource/jsonforms#2570 · 1 comment ·
-
angular core react vue
Difficulty 4/5 3-5 days Newbie friendliness 64/100
eclipsesource/jsonforms#2627 ·
-
react-material: date/time pickers wire `autoFocus`, `onFocus` and `onBlur` to an aria-hidden input Openmaterial react
Difficulty 3/5 1-2 days Newbie friendliness 78/100
eclipsesource/jsonforms#2615 ·
-
Difficulty 3/5 1-2 days Newbie friendliness 45/100
eclipsesource/jsonforms#2599 · 1 comment ·
All issues in eclipsesource/jsonforms
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Eynzof/Hermes-CN-Desktop#610 ·
-
bug clawsweeper:linked-pr-open clawsweeper:needs-live-repro clawsweeper:no-new-fix-pr impact:message-loss issue-rating: 🐚 platinum hermit P2 regression
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
calcite-components needs triage refactor
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Esri/calcite-design-system#15203 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
danielmiessler/LifeOS#2218 ·