Good day,
I have CellItem
components that loses focus for some but not all. It uses Material UI’s TextField
component.
package.json
"@emotion/styled": "^11.13.0",
"@mui/icons-material": "^5.16.7",
"@mui/material": "^5.16.7",
CellItem.js
function CellItem(props) {
const {
rowId,
name,
initialValue,
onUpdateVolumeItem,
maxWidth
} = props;
const [value, setValue] = useState(initialValue);
// more code...
const onValueChange = (e) => {
e.stopPropagation();
e.preventDefault();
let inputValue = e.target.value;
onUpdateVolumeItem(inputValue, rowId, name);
}
return (
<TableCell
scope="row"
padding="none"
sx={{ m: 1, maxWidth }}
onClick={(e) => e.stopPropagation()}
>
<TextField
fullWidth
value={value}
onChange={e => onValueChange(e)}
/>
</TableCell>
);
}
CellItem.defaultProps = {
maxWidth: 110
}
export default React.memo(CellItem);
Here’s the row containing two cells for example.
function VolumeItem(props) {
//....
return (
<TableRow
hover
role="checkbox"
tabIndex={-1}
key={item._id}
sx={{ cursor: 'pointer', backgroundColor: item.isAdded ? "#FFFFE0": "white"}}
>
<CellItem
rowId={item._id}
name="project"
initialValue={item.project}
onUpdateVolumeItem={onUpdateVolumeItem}
/>
<CellItem
rowId={item._id}
name="quarter"
initialValue={item.quarter}
onUpdateVolumeItem={onUpdateVolumeItem}
/>
</TableRow>
);
}
export default React.memo(VolumeItem);
Strangely enough, the "project"
textfield loses focus after one keypress. However, the "quarter"
textfield does not lose focus after several keypress.
In my real project, 3 out of 14 textfields have this problem.
I tried adding keys
in the textfield that aren’t dynamic using the item._id
but didn’t work for all.
Any other thoughts or ideas why is this happening?
Much appreciated!
2
Answers
The root cause is the
item._id
does not have a valid value when a new row is being added.item._id
is used as a key in<TableRow>
.It is a combination of few variables like so:
After careful investigation, the fix is simply to use the appropriate variables as part of the composite key that is valid on initial render. Values that change over time (i.e project) shouldn't be part of the key.
There are several issues in the code above.
VolumeItem
, you have twoCellItem
with the same value for theid
prop. Try removing those props or use unique ids.TextField
is using controlledvalue
butsetValue
is never called.onValueChange
,e.stopPropagation()
ande.preventDefault()
are not necessary.