Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React中的数据表:更改状态与手动更新DOM;数据-*属性与匿名函数_Javascript_Reactjs - Fatal编程技术网

Javascript React中的数据表:更改状态与手动更新DOM;数据-*属性与匿名函数

Javascript React中的数据表:更改状态与手动更新DOM;数据-*属性与匿名函数,javascript,reactjs,Javascript,Reactjs,我有一个React组件,它根据从服务器获取的数据呈现单词表及其翻译。单词被分成若干组,同一个单词可以出现在多个组中。每个组在同一个表中都有一个单独的标记 我使用以下REST API路径从组中删除单词:delete/API/groups/group\u id/words/word\u id。我想将此功能添加到我的React表中,这样每个表行都有一个delete按钮,单击该按钮时会向服务器发送AJAX请求,如果成功,则会从表中删除该行 从语义上来说,从表中删除一行最正确的方法是更新保存数据的组件状态

我有一个React组件,它根据从服务器获取的数据呈现单词表及其翻译。单词被分成若干组,同一个单词可以出现在多个组中。每个组在同一个表中都有一个单独的
标记

我使用以下REST API路径从组中删除单词:
delete/API/groups/group\u id/words/word\u id
。我想将此功能添加到我的React表中,这样每个表行都有一个delete按钮,单击该按钮时会向服务器发送AJAX请求,如果成功,则会从表中删除该行

从语义上来说,从表中删除一行最正确的方法是更新保存数据的组件状态。大概是这样的:

this.setState(状态=>{
const groups=[…state.groups];
const groupIndex=groups.findIndex(group=>group.\u id==group\u id);
const group=groups[groupIndex]={…groups[groupIndex]};//为了不可变性
const words=group.words=[…group.words];
const wordIndex=words.findIndex(word=>word.\u id==word\u id);
单词拼接(单词索引,1);
返回{groups};
});
这将导致组件重新渲染。但是问题来了:仅仅为了删除一个表行而重新呈现整个组件可能是一种过度的行为,因为
this.state.groups
和嵌套的单词数组必须再次遍历(因为
render()
方法调用数组的
map()
方法来构建组件树),在那之后,必须调用React的和解。如果我们关心性能,这似乎是一个糟糕的想法

我知道我应该在React中尽可能避免使用它,但是在这种特殊情况下,为了性能的考虑,返回到良好的旧DOM不是更好吗?我的意思是:

deleteWord=(事件、组id、单词id)=>{
fetch(`/api/groups/${group\u id}/words/${word\u id}`{
方法:“删除”
})。然后(响应=>{
如果(!response.ok)抛出新错误(response.statusText);
}).然后(()=>{
//event.target是已单击的删除按钮
const td=event.target.parentNode;//表格单元格
const tr=td.parentNode;//表行
tr.parentNode.removeChild(tr);
});
};
我仍然可以更新状态以保持同步,但是使用
shoulldcomponentupdate()
返回
false
以避免不必要的计算

所以我的第一个问题是我应该选择哪种方式?也许我错了,表现上的差异不是那么关键

然而,这不是我唯一的问题。我还没有说过在单击其中一个删除按钮时如何检索
group\u id
word\u id
值。这正是我面临的另一个困境

最明显的方法是在呈现时添加匿名函数作为事件侦听器:

const tables=this.state.groups.map(group=>{
const rows=group.words.map({u id,word,translations})=>(
{word}
{translations.join(',')}
));
返回{rows};
});
返回{tables};

但我认为我应该避免,如果组件需要重新渲染,就不要再创建这些函数。因此,我一直在考虑的另一个选择是添加HTML5 data-*属性来存储
组id
单词id
,然后通过
事件
对象访问这些属性。我想知道这是否是一个更好的主意,这是我的第二个问题。

在将对象、数组和函数传递给组件时,可以使用memonization,以防止它们在未更改的情况下重新渲染。即使表作为一个整体已更改,但各行没有更改,因此没有理由重新渲染每一行。如果将行与表组件分离,并且/或者为行提供足够的
键,则重新呈现表不应导致行重新呈现

可以使用
s引用映射数组中的元素,以防止在元素中没有任何更改时重新渲染。当表重新呈现时,它将看到键为“value1”的行没有更改,因此不会重新呈现该行。它将看到缺少键为“value2”的行,从而将其从DOM中删除。它将看到键为“value3”的行没有更改,因此不会重新呈现该行

在示例中使用匿名函数会导致在每次渲染时重新创建该函数。这将导致一个新指针作为道具传递给该元素,从而导致该元素重新渲染。您应该记住内联函数、对象和数组