skip to Main Content

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


  1. Chosen as BEST ANSWER

    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:

    const id = `${project}-${y}-${z}`;
    

    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.


  2. There are several issues in the code above.

    1. In VolumeItem, you have two CellItem with the same value for the id prop. Try removing those props or use unique ids.
    2. TextField is using controlled value but setValue is never called.
    3. In onValueChange, e.stopPropagation() and e.preventDefault() are not necessary.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search