'MUI text field losing focus on state update while using loadable-component package

ColumnFilter.js

This component is responsible for rendering the filter component. I have just posted the part which renders FlterWrapper component (which is relevant). It contains a state which is passed on to the child, whenever change happens in child's input, state is updated in this component.

<FilterWrapper
  inputKey={inputKey}
  filter={filter}
  updateFilterOnChange={updateFilterOnChange}
  filterData={filterData}
/>

FilterWrapper.js

This component is responsible for choosing between which component to be rendered based on provided type. @loadable/component package is used for code splitting, which is actually causing this issue. If I remove the loadable imports and directly import the filter components, it works focus to the text field remains intact, but with use of loadable package, it causes re-render to the FilterWrapper and hence re-render appears in TextFilter component as well, which causes focus loss on text field.

function FilterWrapper({ filter, updateFilterOnChange, filterData }) {
  const TextFilter = loadable(() => import('./TextFilter'));
  const DateRangeFilter = loadable(() => import('./DateRangeFilter'));
  const RadioFilter = loadable(() => import('./RadioFilter'));
  const CheckboxFilter = loadable(() => import('./CheckboxFilter'));

  switch (filter.type) {
    case 'text-search':
      return (
        <TextFilter
          filter={filter}
          updateFilterOnChange={updateFilterOnChange}
          filterData={filterData}
        />
      );
    case 'date-range-selection':
      return (
        <DateRangeFilter
          filter={filter}
          updateFilterOnChange={updateFilterOnChange}
          filterData={filterData}
        />
      );
    case 'radio-selection':
      return (
        <RadioFilter
          filter={filter}
          updateFilterOnChange={updateFilterOnChange}
          filterData={filterData}
        />
      );
    case 'checkbox-selection':
      return (
        <CheckboxFilter
          filter={filter}
          updateFilterOnChange={updateFilterOnChange}
          filterData={filterData}
        />
      );
    default:
      return null;
  }
}

TextFilter.js

This is where MUI TextField is rendered.

function TextFilter({ inputKey, filter, updateFilterOnChange, filterData }) {
  const key = 'searchText';
  const onChange = event => {
    const searchValue = event.currentTarget.value;
    updateFilterOnChange([
      {
        key,
        value: searchValue,
      },
    ]);
  };

  const useStyles = makeStyles(() => ({
    textField: {
      width: '25ch',
    },
  }));
  const classes = useStyles();

  return (
    <Box padding="0 16px">
      <TextField
        key={inputKey}
        placeholder="Enter keyword or id"
        onChange={onChange}
        value={filterData[key]}
        label="Contains"
        className={classes.textField}
        name={filter.name}
      />
    </Box>
  );
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source