简体   繁体   English

state改变后如何重新渲染

[英]How to re-render after state has changed

In React, I am working with a Kendo grid.在 React 中,我正在使用 Kendo 网格。 I have a grid that is filled with a state array like this:我有一个充满 state 数组的网格,如下所示:

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.因此,在渲染时,我在 useEffect 中调用 API 并用对象数组填充 tempAtributi state。 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.之后,我有一列删除,您可以在其中单击和 onClick,检查该属性是否在对象的 tempAtributi 数组内。 If it is, I update tempAtributi state with an array of object minus the object that is removed.如果是,我用 object 减去已删除的 object 的数组更新 tempAtributi state。 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):完成删除后,我必须单击确认调用 API 并将 tempAtributi state 设置为更新/新值(如果我在单击确认后调用 services.getTemplateAtributi,我将获得更新值):

<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.如果我单击删除一次或多次(无需确认)一切正常,如果我控制台记录 state,它还没有删除 object,但问题是我仍然可以在网格中看到 object,即使它是不再在 tempAtributi state 中。 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.我想在单击 remmove 后刷新网格,以便该行不存在。我不知道如何在删除后刷新网格,因为如果我调用 useEffect,它将调用 API 并将其设置为乞讨值。 Help needed!需要帮助!

My first guess would be removing deep object copy.我的第一个猜测是删除深层 object 副本。 Since cloning objects in JavaScript ties them deeply.由于 JavaScript 中的克隆对象与它们紧密相关。 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.正如您所注意到的,a 和 b 具有相同的值,但我们只改变了其中一个。 You can kill this tie using b = JSON.parse(JSON.stringify(a)) , which is most common approach.您可以使用b = JSON.parse(JSON.stringify(a))这种关系,这是最常见的方法。

So in your example your delete function should look like this:因此,在您的示例中,您的 delete function 应如下所示:

const Remove = () => {
  if (indexObj > -1) {
    const deepCopy = JSON.parse(JSON.stringify(tempAtributi));
    deepCopy.splice(indexObj,1);
    setTempAtributi(deepCopy);
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM