updated value is not displayed with custom Edit component
material-react-table version
v1.14.0
react & react-dom versions
v18.2.0
Describe the bug and the steps to reproduce it
Following the pattern from this discussion on custom edit components, I've created a simple example with a custom Select widget here. Here's the relevant part:
{
accessorKey: "state",
header: "State",
Edit: ({ row, cell }) => (
<Select
value={cell.getValue<string>()}
onChange={(e) => (row._valuesCache["state"] = e.target.value)}
>
<MenuItem key="Alabama" value="Alabama">
Alabama
</MenuItem>
<MenuItem key="Zanzibar" value="Zanzibar">
Zanzibar
</MenuItem>
</Select>
),
}
Selecting a value does actually set the new value, which I can see after hitting the Save button -- but it does not update the temporary value displayed while editing, so there's no visual indication that a new item was selected. (This is complicated to explain but trivial to see -- just try the demo.)
I thought that this change might fix it:
<Select
value={row._valuesCache["state"]}
onChange={(e) => (row._valuesCache["state"] = e.target.value)}
>
But surprisingly that had no effect.
In general the row._valuesCache thing seems problematic ... seems like we need a more principled way of accessing and setting the row state in a custom editor. For reference, here's how MUI does it -- though I don't particularly like their solution. Seems to me the cleanest and most elegant solution is for Edit params to just give me what I need:
{
accessorKey: "state",
header: "State",
Edit: ({ value, setValue }) => ( // <-- notional new props here
<Select
value={value}
onChange={e => setValue(e.target.value)}
>
<MenuItem key="Alabama" value="Alabama">
Alabama
</MenuItem>
<MenuItem key="Zanzibar" value="Zanzibar">
Zanzibar
</MenuItem>
</Select>
)
}
(If setValue just calls row._valuesCache[accessorKey] = value under the hood, great, but as the MRT user I'd rather not know about it.)
Minimal, Reproducible Example - (Optional, but Recommended)
See CodeSandbox demo.
Screenshots or Videos (Optional)
No response
Do you intend to try to help solve this bug with your own PR?
No, because I do not know how
Terms
- [X] I understand that if my bug cannot be reliably reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.
@githorse did you able to solve this issue? I'm also facing this issue
@mbmohib Unfortunately not. At the moment I'm just using the built-in select functionality, like this:
{
...
muiTableBodyCellEditTextFieldProps: {
select: true,
options: myOptions.map(({value, label}) => (
<MenuItem key={value} value={value}>{label}</MenuItem>
)
}
But it's not what I want -- my actual custom Select widget has other functionality (styling) that I'm missing here.
After hours of digging: table.options.data
@Drecula could you elaborate? What do I do with table.options.data?
@githorse If you check the TextField component, whenever you change the table gets re-rendered. But with the custom component when we update the cache value, it does not re-render. So if we make the parent component force to rerender, you will see this value will be populated.
for those who are suffering from the same issue us the function row.toggleSelected this will update the component after value is changed>
{
type: "autoComplete",
autoCompleteOptions: roles.data,
header: "الدور",
accessorKey: "role",
enableHiding: false,
Edit: ({ row }) => {
return (
<Autocomplete
disablePortal
id={"autoComplete"}
key={"autoComplete"}
value={row._valuesCache["role"] || null}
onChange={(_, value) => {
row._valuesCache["role"] = value;
row.toggleSelected(row._valuesCache["role"]);
}}
isOptionEqualToValue={(option, value) => option._id === value._id}
getOptionLabel={(option) => option.title}
fullWidth
options={roles.data || []}
renderInput={(params) => (
<TextField
key={"autoCompleteText"}
{...params}
label={"الدور"}
/>
)}
/>
);
},
},