Javascript 手动调用'createElement'是一种糟糕的形式吗?

Javascript 手动调用'createElement'是一种糟糕的形式吗?,javascript,reactjs,Javascript,Reactjs,我在React项目的任何地方都使用JSX,因为我当然是这样。 但在一些情况下,使用createElement尤其有用 这里有一个这样的例子,它代表了我的典型用例。 我有一个大小合理的字符串,我想在 const splitOnCR = stdin.split("\r"); const joinerStyle = { color: "#337ab7", // Bootstrap primary color } const joiner = <tt style={joinerStyl

我在React项目的任何地方都使用JSX,因为我当然是这样。 但在一些情况下,使用
createElement
尤其有用

这里有一个这样的例子,它代表了我的典型用例。 我有一个大小合理的字符串,我想在

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>&nbsp;</span>,  // show final newlines, if any
);
这确实产生了

我在这里看到的另一种方法是为字符串中的每个字符生成一个单独的
或其他任何内容,然后将它们全部呈现在一个数组中。 我不想那样做。 这会让我伤心

我在更改字符串的同时检查了DOM,当我附加到字符串时,React似乎只会很高兴地更改最后一个文本节点,当我添加回车符时,它只会创建一个额外的
。这是我所期望的(和希望的)

但我也可以想象,对
createElement
的这种可变调用可能会在某种程度上混淆差分算法毕竟,我们在渲染数组时通常需要
key
s。 我只是不知道那是什么或者会有什么影响


这安全吗?好吗?还有其他方法吗?

JSX只是
React.createElement
的语法糖。React实际上并不关心(或知道)您是否手动编写了
React.createElement

但我也可以想象,对
createElement
的这种可变调用可能会在某种程度上混淆差分算法毕竟,我们在渲染数组时通常需要键


是和否。您所做的与JSX中的相同

renderA: <div><span>first</span></div>
renderB: <div><span>first</span><span>second</span></div>
=> [insertNode <span>second</span>]
在开头插入元素是有问题的。React将看到两个节点都是跨度,因此会进入变异模式

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>]
renderA:第一个
renderB:第二优先
=>[replaceAttribute textContent'第二个'],[insertNode第一个]
有许多算法试图找到转换元素列表的最小操作集。Levenshtein距离可以通过在O(n2)中的单元素插入、删除和替换找到最小值。即使我们使用Levenshtein,也不会发现节点何时移动到另一个位置,而这样做的算法的复杂性要差得多

钥匙 为了解决这个看似棘手的问题,引入了可选属性。您可以为每个子级提供一个用于进行匹配的密钥。如果指定一个键,React现在可以使用哈希表在O(n)中查找插入、删除、替换和移动

renderA:第一个
renderB:第二优先
=>[insertNode秒]
实际上,找到一把钥匙并不难。大多数情况下,您将要显示的元素已经具有唯一的id。如果不是这样,您可以向模型中添加新的id属性,或者对内容的某些部分进行散列以生成密钥。请记住,密钥只需在其同级中唯一,而不是全局唯一


“在JSX中,您所做的将等同于此”——嗯,不完全是这样;如果您的
有时不在那里,则可以进行更好的类比。在JSX中,通常的方法是编写
{cond&&&}
,但在这种情况下,参数仍然存在,只是可能是错误的。值得一提的是,我已经阅读了
文档(很多次!
:)
)。我想我的基本问题是:如果React可以用我的用例解决这个问题,为什么这个解决方案不能通用化,使
key
s完全不必要呢?嗯,我简化了。您怎么会认为在没有键的情况下执行了最佳树转换?文档非常清楚
key
的用途。不知道还有什么可以补充的。
renderA: <div><span>first</span></div>
renderB: <div><span>second</span><span>first</span></div>
=> [replaceAttribute textContent 'second'], [insertNode <span>first</span>]
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>]