我在我的React项目中到处使用JSX,因为我当然是。
但是有一些情况下使用createElement
特别有帮助。
这是一个这样的例子,它代表了我的典型用例。
我有一个合理大小的字符串,我希望在<pre>
标记中显示,但我希望\r
(0x0D
)字符的所有实例都显示为{{1} } 使用不同的颜色。
我可以很容易地实现如下
<CR>
确实产生了
我在这里看到的替代方案是为字符串中的每个字符生成单独的const splitOnCR = stdin.split("\r");
const joinerStyle = {
color: "#337ab7", // Bootstrap primary color
}
const joiner = <tt style={joinerStyle}>{"<CR>"}</tt>;
let parts = new Array(splitOnCR.length * 2 - 1);
for (let i = 0; i < parts.length; i++) {
if (i % 2 === 0) {
parts[i] = splitOnCR[i / 2];
} else {
parts[i] = joiner;
}
}
const style = {
fontFamily: "monospace", // override Menlo or whatever
};
return React.createElement(
"pre",
{style},
...parts,
<span> </span>, // show final newlines, if any
);
或<tt>
或其他内容,然后将它们全部呈现在数组中。
我不想这样做。
这会让我伤心。
我在更改字符串时检查了DOM,看起来React会很乐意更改最后一个文本节点,因为我追加到字符串,它只会在我创建一个额外的<span>
时添加回车。这正如我所料(并希望)。
但是我也可以想象这种对<tt>
的可变调用可能会以某种方式混淆差异算法 - 毕竟,在渲染数组时我们通常需要createElement
。
我只是不知道那是什么或影响是什么。
那么这样安全吗?好吗?还有其他方法吗?
答案 0 :(得分:0)
JSX只是React.createElement
的语法糖。 React真的不关心(或知道)你是否手动编写React.createElement
。
但是我也可以想象这种对
createElement
的可变调用可能会以某种方式混淆差异算法 - 毕竟,在渲染数组时我们通常需要键。
是和否。你在做什么在JSX中等同于这个。
<parent>
<child1 />
<child2 />
</parent>
即。你只需要一个带有多个&#34;直接&#34;孩子,而不是传给孩子一个阵列。您之前可能已经看过这个,因为这很常见,因此您的解决方案对于React而言并不比使用JSX更糟糕。
请注意,任何元素都可以拥有密钥。如果传递数组,React只会强制执行它。
现在问题是,使用key
有什么好处(见下一节)。
我只是不知道那是什么或影响是什么。
您可能想阅读https://facebook.github.io/react/docs/reconciliation.html。引用相关部分:
List-wise diff
有问题的案例
为了让孩子和解,React采用了一种非常天真的方法。它会同时覆盖两个孩子的列表,并在出现差异时生成突变。
例如,如果在末尾添加元素:
renderA: <div><span>first</span></div> renderB: <div><span>first</span><span>second</span></div> => [insertNode <span>second</span>]
在开头插入元素是有问题的。 React将看到两个节点都是跨距,因此会进入突变模式。
renderA: <div><span>first</span></div> renderB: <div><span>second</span><span>first</span></div> => [replaceAttribute textContent 'second'], [insertNode <span>first</span>]
有许多算法试图找到转换元素列表的最小操作集。 Levenshtein距离可以在O(n2)中使用单个元素插入,删除和替换找到最小值。即使我们使用Levenshtein,当节点移动到另一个位置时,这并不能找到,并且算法的复杂程度要差得多。
键
为了解决这个看似棘手的问题,我们引入了一个可选属性。您可以为每个孩子提供用于进行匹配的密钥。如果你指定一个键,React现在能够找到插入,删除,替换并使用哈希表在O(n)中移动。
renderA: <div><span key="first">first</span></div> renderB: <div><span key="second">second</span><span key="first">first</span></div> => [insertNode <span>second</span>]
在实践中,找到钥匙并不是很难。大多数情况下,您要显示的元素已经具有唯一ID。如果情况并非如此,您可以向模型添加新的ID属性,或者对内容的某些部分进行哈希以生成密钥。请记住,密钥只能在其兄弟姐妹中独一无二,而不是全局唯一。