'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 |
|---|
