ctxToMultiEnumControlProps omits props.options from its useMemo dependency array, unlike its enum/oneOf-enum siblings: multi enum control never picks up externally-updated options

Open Beginner friendly
#2,624 0 comments 0 reactions 0 assignees View on GitHub

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
  1. Render a control using withJsonFormsMultiEnumProps, wrapped by a custom HOC that supplies options as a prop asynchronously (e.g. setTimeout(() => setOptions([...]), 0) before passing options={options} down).
  2. Observe that the wrapped component's options prop stays at its initial (empty) value even after the async update, while the identical pattern using withJsonFormsOneOfEnumProps correctly 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from eclipsesource/jsonforms

All issues in eclipsesource/jsonforms

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.