React: 有关“ props.children”的问题

创建于 2018-05-26  ·  6评论  ·  资料来源: facebook/react

您是否要请求功能或报告错误
只是问题

有关道具的一些问题

React.Children的官方React文档中,您可以看到this.props.children是“不透明的数据结构”。
这到底是什么意思?

我认为props.children数据结构的透明度通常存在三种可能性:

情况1: props.children数据结构的每个方面都是开放的且定义明确。

如果这是正确的,那么术语“不透明的数据结构”将是完全错误的。
因此,“情况1”显然不是这种情况。

情况2: props.children数据结构的任何方面均未打开或清除。

这意味着每当您使用props.children您始终必须将其与React.Children组合使用,因为React.Children是唯一的一个(嗯,真的是唯一的一个吗?)谁知道props.children的实际数据结构。

但这意味着它不应该被允许使用

javascript // This is used almost everywhere (even in the official React documentation) <div>{this.props.children}</div>

也不

javascript // This is often seen with the "Function as child" pattern MyComponent.propTypes = { children: PropTypes.func.isRequired, };

由于这两个示例都很常见,因此“案例2”显然也不是这种情况。

情况3: props.children数据结构的某些方面是开放的且定义明确。

这将打开“案例2”中一个或两个示例都有效的可能性。
但是,这意味着应该有一个准确的规范,说明props.children哪些方面是正确公开的,哪些方面是真正不透明的。
也许我已经错过了React文档中的某些内容,但是我认为那里并没有确切指定它,是吗?

最后但同样重要的是:

为什么在某些子(一个或多个)总是总是一个数组的情况下(例如在“ Preact”中完成),为什么不正确地设置props.children ? 那会使事情变得容易得多,不是吗?

在此先感谢您的澄清。

Question

最有用的评论

_不透明数据结构_指的是children可以有很多东西:数组,片段,单个元素,字符串文字等。

_React.Children_包含一些方法,可让您以统一的方式使用各种children _,并且绝对不是与它们进行交互的唯一方法。

如果有一些子项(一个或多个)总是总是一个数组(例如在“ Preact”中完成),为什么props.children也不正确?

children除了它在JSX中有简写之外,它的属性与其他任何属性一样。 实际上,您可以将其指定为:

<Component children={...}/>

当React需要更新DOM时,告诉两个单项数组是否相同比两个基本值(例如字符串)是否相同要昂贵得多。

话虽如此,我确实认为React.Children文档可能会有所扩展,但这是登录Reactjs / reactjs.org存储库的问题。

这篇文章可能会澄清一些事情,对我有用!

所有6条评论

_不透明数据结构_指的是children可以有很多东西:数组,片段,单个元素,字符串文字等。

_React.Children_包含一些方法,可让您以统一的方式使用各种children _,并且绝对不是与它们进行交互的唯一方法。

如果有一些子项(一个或多个)总是总是一个数组(例如在“ Preact”中完成),为什么props.children也不正确?

children除了它在JSX中有简写之外,它的属性与其他任何属性一样。 实际上,您可以将其指定为:

<Component children={...}/>

当React需要更新DOM时,告诉两个单项数组是否相同比两个基本值(例如字符串)是否相同要昂贵得多。

话虽如此,我确实认为React.Children文档可能会有所扩展,但这是登录Reactjs / reactjs.org存储库的问题。

这篇文章可能会澄清一些事情,对我有用!

非常感谢@danburzo的回答和澄清。
在您回答之后,很明显,我完全误解了那里的“不透明”一词。
React文档只是想说props.children的数据结构是一个完全定义的联合类型,并且它的具体表示形式有所不同(就像联合类型总是一样)。

我刚刚发现了一个解决了相同主题的老问题-想知道这些更改是怎么回事?!? (我在reactjs.org => reactjs / reactjs.org#914中打开了一个问题):

https://github.com/facebook/react/pull/6018/files/91223423410f107ff83a8a6ce3158c488247292f?short_path=ef51787#diff -ef51787305cfed62f6f564284762d4de

尽管如此,我仍然想再问第二个问题:
如果恰好有一个孩子,为什么“ props.children”不是数组(如果您不知道背景=>如果名称是“ children”或“ items”,那么这实际上违反了最小惊讶原则)或您通常希望获得的“令牌”)?
确实是出于性能原因吗? 我真的看不到下面的“ checkResult”计算很费时:

const
  child1 = ...,
  child2 = ...,
  child1IsArray = Array.isArray(child1),
  child2IsArray = Array.isArray(child2),

  checkResult = child1IsArray && child2IsArray
     && child1.length === 1 && child2.length === 1
     && child1[0] === child2[0]; 

抱歉,再次询问似乎有点烦人-但我真的很想知道该设计决定的确切原因...。

很高兴能为您解答第一部分的问题! 不幸的是,关于为什么未将单个子代表示为一个单项数组,我没有_exact_答案。 但是,我试图指出,您仍然可以有效地通过一个孩子作为普通道具(而不是JSX的缩写),这一事实使我无意中掩盖了与表现有关的假设。

@danburzo再次感谢您的回答。

嗯,坦率地说,我希望React团队中的某人会记得设计决定的真正原因...
因为React中的子道具处理确实存在一些细微的问题。
例如,问一个React新手,以下示例中的组件Test1和Test2是否表现相同(您-作为React专业人士-知道答案为“否” => Test2将在DEV上警告有关丢失的键,而Test1将不是-但是,如果您是新手,这真的是您所期望的吗?!?)

const
  h = React.createElement,
  Test1 = () => h('div', null, h('br'), h('br')),
  Test2 = () => h('div', { children: [h('br'), h('br')] });

ReactDOM.render(
  h('div', null, h(Test1), h(Test2)),
  document.getElementById('container')
);

顺便说一句:如果允许使用Test2,则在实现某些createElement替换(例如,某些超脚本功能)时,这将带来一些微妙的性能优势。

另一个例子:问一个React新手,如果要求所有孩子都应满足一定条件,那么“孩子:PropTypes ....”会是什么样子。 我认为这将不容易回答(至少对于新手而言)。

给React团队:如果真正不知道设计决定的原因,或者只是出于口味问题,那么当然可以解决这个问题。

我假设不为单个孩子使用数组的决定是为了避免不必要的数组分配。

因为React中的子道具处理确实存在一些细微的问题。

我们通常不建议使用显式的children道具。 大多数用户还使用JSX而不是直接调用React.createElement ,因此您提到的问题通常不是问题。

@aweary谢谢您的回答

此页面是否有帮助?
0 / 5 - 0 等级