In React, I am working with a Kendo grid. I have a grid that is filled with a state array like this:
const [tempAtributi, setTempAtributi] = useState([]);
// ...
const MyCommandCell = (props) => {
const indexObj = tempAtributi.findIndex(
(e) => e.atribut_id === props.dataItem.atribut_id
);
const Remove = () => {
if (indexObj > -1) {
const lista = tempAtributi;
lista.splice(indexObj, 1);
setTempAtributi(lista);
}
};
return (
<td className="k-command-cell">
<Button
className="k-button k-button-md k-rounded-md k-button-solid k-button-solid-base k-grid-remove-command"
onClick={() => Remove()}
>
<FaTrash /> Remove
</Button>
</td>
);
};
const Cell = (props) => <MyCommandCell {...props} />;
useEffect(() => {
(async () => {
try {
const resAtr = await services.getTemplateAtributi(
state.data.sn_template_id
);
setTempAtributi(resAtr.data.rlista);
} catch (e) {
console.log(e);
}
})();
}, []);
//...
return (
<>
<Grid data={tempAtributi}>
<GridColumn field="name" title="Atribut" filter="text" />
<GridColumn cell={CommandCell} title="remove" filter="text" />
</Grid>
</>
);
So, on render I call an API in useeffect and fill the tempAtributi state with an array of objects. My grid is filled. After that, I have a column Remove where you can click and onClick, it is checked if that atribute is inside the tempAtributi array of objects. If it is, I update tempAtributi state with an array of object minus the object that is removed. After I finished removing, I must click confirm which calls an API and sets tempAtributi state as the updated/new value ( if I call services.getTemplateAtributi after Confirm is clicked I get updated values):
<Button themeColor={"primary"} style={{marginTop:'2%', marginRight:'2%'}} onClick={() => Confirm()}>
Confirm
</Button>
If I click remove one or more times(without confirming) everything is ok, if I console log the state, it hasn't got the removed object, but the thing is that I can still see the object in the grid even though it is not in the tempAtributi state anymore. I want to refresh the grid after I click remmove so that row is not there.I don't know how to refresh the grid after the removal, because if I call useeffect, it will call the API and set it to the begging values. Help needed!
CodePudding user response:
My first guess would be removing deep object copy. Since cloning objects in JavaScript ties them deeply. You can test this with one simple example:
const a = { b: { c: 'd' } } }
const b = a
b.b.c = 'e'
console.log(a, b)
As you notice, both a and b, has same value, but yet we mutated only one of them.
You can kill this tie using b = JSON.parse(JSON.stringify(a))
, which is most common approach.
So in your example your delete function should look like this:
const Remove = () => {
if (indexObj > -1) {
const deepCopy = JSON.parse(JSON.stringify(tempAtributi));
deepCopy.splice(indexObj,1);
setTempAtributi(deepCopy);
}
}