我已经从事反应超过一年了。我主要使用.map,.forEach,.filter或如果对象是Object.keys和Object.values来迭代数组。
但是向jsx元素添加唯一键的不同方法是什么。到目前为止,我已经习惯了以下内容
使用数据中的唯一ID作为键prop的键:
const data= [{"id": "01", "name": "abc"}, {"id": "02", "name": "xyz"}];
render(){
const items = data.map(item => {
return <span key={item.id}>{item.name}</span>;
}
return(
<div>
{items}
</div>
)
}
使用索引作为关键道具的关键:
const data= [{"id": "01", "name": "abc"}, {"id": "02", "name": "xyz"}];
render(){
const items = data.map((item, i) => {
let keyValue = i+1;
return <span key={keyValue}>{item.name}</span>;
}
return(
<div>
{items}
</div>
)
}
首先, 避免使用随机密钥 。
有很多写键的方法,有些会比其他的性能更好。
要了解我们选择的密钥如何影响性能,有必要了解React的对帐算法。
https://reactjs.org/docs/reconciliation.html
tl; dr引入了一种启发式方法,用于比较虚拟DOM树与该VDOM树的n个节点进行比较O(n)。这种启发式方法可以分为以下几点:
<Button />
到<NotButton />
),会导致我们的按钮将要卸载其子项以及NotButton也将与其子项一起安装。现在假设我们有这个:
<div>
<Button title="One" />
<Button title="Two" />
</div>
我们想在下一个渲染中向DOM添加一个Button,例如
<div>
<Button title="Zero" />
<Button title="One" />
<Button title="Two" />
</div>
该算法将如下所示:
<divs>
在两个VDOM中进行比较。由于它们具有相同的类型,因此我们无需重新创建新树。道具是相同的,因此此时没有更改可应用于DOM。One
与进行比较Zero
。协调器检测到这里是道具更改,然后使用此标题更新DOM。Two
与进行比较One
。协调器还会在此处检测道具更改,并使用DOM编写此更改。Button
添加的对象是最后一个孩子,因此Button
在VDOM 创建一个新实例,并将此更改写入DOM。请注意,它们在DOM上有许多操作,因为它通过索引比较了组件。
现在,我们可以通过告知协调器这些实例应被重用来解决此问题。现在,让我们有这个:
<div>
<Button title="One" key="One" />
<Button title="Two" key="Two" />
</div>
我们想在下一个渲染中向DOM添加一个Button,例如
<div>
<Button title="Zero" key="Zero" />
<Button title="One" key="One" />
<Button title="Two" key"Two" />
</div>
该算法将如下所示:
<divs>
在两个VDOM中进行比较。由于它们具有相同的类型,因此我们无需重新创建新树。道具是相同的,因此此时没有更改可应用于DOM。Button
调解员说,这是一个。“并且有钥匙”(“一个”)。然后,在新的子代列表中寻找密钥相同的子代。“哦,我遇到了!” 但是调解员意识到 道具没有改变 。这样一来,将不需要DOM操作。Button
,它将用keys
而不是进行比较index
。意识到它是同一个实例,并且没有更改道具,因此React决定不在DOM上应用更改。Button
具有“零”键的键,由于 不存在具有相同键的子键 ,因此意识到应该在VDOM上创建实例,并且此更改应写在DOM上。因此,通过可预测的内容使用密钥有助于协调器在DOM上执行较少的操作。健康键是可以从正在映射的对象中推断出来的键,例如name
,如果要转换为id
,url
则为,甚至urls
为<imgs />
。
那key=index
呢 将不起作用,因为默认情况下,协调程序会按位置(即其索引)进行比较。
这些键应该是全局唯一的吗?不必要。这些在兄弟姐妹之间应该是唯一的,因此协调程序可以在节点的子节点进行迭代时区分它们。
随机密钥呢?应不惜一切代价避免这些情况。如果每个渲染上都有一个键更改,这将使React破坏并在VDOM上创建实例(并因此在DOM上进行额外的写操作),因为在新的子级中没有找到带有键的组件,而是一个新的具有相同的类型。
如果渲染输出像
<div>
<Button key={randomGenerator()} />
</div>
然后,每次render
执行(例如,由于道具/状态更改,或者即使其父级被重新渲染并shouldComponentUpdate
返回true
),randomGenerator()
也会生成一个新密钥。这将像:
‘嘿!我找到了一个Button
带F67BMkd==
钥匙的钥匙,但下一个没有找到。我将其删除。’哦!我遇到了Button
一把SHDSA++5
钥匙!让我们创建一个新的。
每当协调程序告诉您应该删除并卸载实例时,其内部状态都会丢失;即使我们再次安装它。在这种情况下,将不会保留VDOM上的实例。
该Button
是一样的,但在调解DOM做了一个烂摊子。
希望能帮助到你。
问题内容: 我正在React中尝试执行以下操作(其中ObjectRow是一个单独的组件): 我意识到并理解为什么这是无效的,因为它映射到函数调用。但是,由于来自模板领域并且是的新手,所以我不确定如何实现上述目标(多次添加组件)。 问题答案: 就像您只是在调用JavaScript函数一样。您不能使用循环来调用函数的参数: 查看如何将函数作为参数传递给循环-导致语法错误。 但是您可以创建一个数组,然后
为了更新一些证书,我必须将jks密钥库转换为PKCS#12密钥库,并在转换过程中包含私钥。我们收到的密钥库是JKS密钥库,但是我们的网络服务器使用PKCS#12密钥库,我们收到的密钥库只包含证书,而不包含私钥。 我试着用谷歌搜索并阅读SO的几个条目,我只想出了一个解决方案,这似乎更像是一个变通方法,而不是一个好的方法,所以我想知道是否有人有更好的方法如何注入私钥,并以更简单的方式从jks密钥库转换
问题内容: 我正在React中尝试做类似以下的事情(其中ObjectRow是一个单独的组件): 我意识到并理解为什么这是无效的,因为它映射到函数调用。但是,由于来自模板领域并且是的新手,所以我不确定如何实现上述目标(多次添加组件)。 问题答案: 就像您只是在调用JavaScript函数一样。您不能使用循环来调用函数的参数: 查看如何将函数作为参数传递给循环,这当然是语法错误。 但是您可以创建一个数
我有一个比较简单的问题,就是尝试将内联脚本添加到React组件中。我目前所掌握的: 我还尝试过: 这两种方法似乎都无法执行所需的脚本。我想我错过的是一件简单的事。有人能帮忙吗? PS:忽略foobar,我有一个真实的id实际上在使用,我不想分享。
我对react很陌生(我只使用过abit类),我想把输入值添加到并在屏幕上写出来,但我的大脑被锁住了,我不知道如何...
鉴于这一目标: 我想在JSX中循环使用它。这项工作: 但这并不是(社会未定义): 第二个示例中未定义社交的原因是什么?我假设内括号存在范围界定问题,但我尚未成功修复它。 我可以用对象键做一个,也可以像本文中那样做,但这与我的工作示例没有太大区别。 为了清楚起见,我在第二个示例中只想更清楚地说明作用域问题(或者语法错误,如果是的话)。