Custom Renderer not working in Production Build

Hello,

I have a strange problem, where my custom renderer does work in development build, but does not work correctly in the production build ( vite react app served with nginx). I changed the One Of Renderer to use a select menu instead of tabs. But if I insert a value in one of the fields of the selected option, the other fields will get cleared. Does anyone have an idea what went wrong?

This is what I changed the OneOfRenderer to:

import { useCallback, useState } from 'react';
import isEmpty from 'lodash/isEmpty';

import { TabSwitchConfirmDialog } from './TabSwitchConfirmDialog';

import {
  CombinatorRendererProps,
  createCombinatorRenderInfos,
  createDefaultValue,
  isOneOfControl,
  JsonSchema,
  OwnPropsOfControl,
  RankedTester,
  rankWith,
} from '@jsonforms/core';
import { Hidden, MenuItem, Select } from '@mui/material';
import { JsonFormsDispatch, withJsonFormsOneOfProps } from '@jsonforms/react';
import CombinatorProperties from './CombinatorProperties';

export interface OwnOneOfProps extends OwnPropsOfControl {
  indexOfFittingSchema?: number;
}

const OneOfRenderer = ({
  handleChange,
  schema,
  path,
  renderers,
  cells,
  rootSchema,
  id,
  visible,
  indexOfFittingSchema,
  uischema,
  uischemas,
  data,
}: CombinatorRendererProps) => {
  const [confirmDialogOpen, setConfirmDialogOpen] = useState(false);
  const [selectedIndex, setSelectedIndex] = useState(indexOfFittingSchema || 0);
  const [newSelectedIndex, setNewSelectedIndex] = useState(0);
  const handleClose = useCallback(
    () => setConfirmDialogOpen(false),
    [setConfirmDialogOpen]
  );
  const cancel = useCallback(() => {
    setConfirmDialogOpen(false);
  }, [setConfirmDialogOpen]);
  const oneOfRenderInfos = createCombinatorRenderInfos(
    (schema as JsonSchema).oneOf as JsonSchema[],
    rootSchema,
    'oneOf',
    uischema,
    path,
    uischemas
  );

  const openNewTab = (newIndex: number) => {
    handleChange(
      path,
      createDefaultValue(oneOfRenderInfos[newIndex].schema)
    );
    setSelectedIndex(newIndex);
  };

  const confirm = useCallback(() => {
    openNewTab(newSelectedIndex);
    setConfirmDialogOpen(false);
  }, [handleChange, createDefaultValue, newSelectedIndex]);

  const handleSelectChange = (event : any) => {
    const newOneOfIndex = event.target.value;
    setNewSelectedIndex(newOneOfIndex);
    if (isEmpty(data)) {
      openNewTab(newOneOfIndex);
    } else {
      setConfirmDialogOpen(true);
    }
  };
  
  return (
    <Hidden xsUp={!visible}>
    <CombinatorProperties
      schema={schema}
      combinatorKeyword={'oneOf'}
      path={path}
      rootSchema={rootSchema}
    />
    <Select className="w-full mb-2" value={selectedIndex} onChange={handleSelectChange}>
        {oneOfRenderInfos.map((oneOfRenderInfo, index) => (
          <MenuItem key={oneOfRenderInfo.label} value={index}>
            {oneOfRenderInfo.label}
          </MenuItem>
        ))}
      </Select>
      {oneOfRenderInfos.map(
        (oneOfRenderInfo, oneOfIndex) =>
          selectedIndex === oneOfIndex && (
            <JsonFormsDispatch
              key={oneOfIndex}
              schema={oneOfRenderInfo.schema}
              uischema={oneOfRenderInfo.uischema}
              path={path}
              renderers={renderers}
              cells={cells}
            />
          )
      )}
      <TabSwitchConfirmDialog
        cancel={cancel}
        confirm={confirm}
        id={'oneOf-' + id}
        open={confirmDialogOpen}
        handleClose={handleClose}
      />
  </Hidden>  
  );
};

export const oneOfControlTester: RankedTester = rankWith(
  10,
  isOneOfControl
);

export default withJsonFormsOneOfProps(OneOfRenderer);

Thank you for the help.

Best regards,
Philip

Hi @pbarth,

On a first look your code looks fine, which makes sense as it’s largely a copy of the MaterialOneOfRenderer.

I’m not really sure what could be causing this problem. So I would advise to debug.

All (proper) changes in JSON Forms go through the coreReducer. So you should debug in there. Changes coming from inputs are handled in UPDATE_DATA, changes coming from outside the form are handled in UPDATE_CORE. In one of these methods the data seems to be modified incorrectly in your error case.

If the data changes without one of these actions being invoked, then this means there is some direct data manipulation not going through the proper channels. This data manipulation must be avoided.