Home > Enterprise >  How to re-render after state has changed
How to re-render after state has changed

Time:04-20

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);
  }
}
  • Related