機能をリクエストしバグを報告しますか?
質問だけ
React.Childrenの公式Reactドキュメントでは、 this.props.children
が「不透明( OPAQUE)データ構造」であると読むことができます。
それは正確にはどういう意味ですか?
props.children
のデータ構造の透明性には、一般的に3つの可能性があると思います。
props.children
データ構造のすべての側面が開かれ、明確に定義されています。これが正しければ、「不透明なデータ構造」という用語は完全に間違っているでしょう。
したがって、「ケース1」は明らかにそうではありません。
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」も明らかにそうではないようです。
props.children
データ構造のいくつかの側面はオープンであり、明確に定義されています。これにより、「ケース2」の例の一方または両方が有効である可能性が開かれます。
しかし、それは、 props.children
のどの側面が適切かつオープンに定義され、どの側面が本当に不透明であるかを正確に指定する必要があることを意味します。
Reactのドキュメントで何かを見逃しているかもしれませんが、実際には正確に指定されていないと思いますね。
一部の子(1つ以上)が常に配列である場合(たとえば「Preact」で行われるように)、 props.children
が正確にないのはなぜですか? それは物事をとても簡単にするでしょうね?
明確化のために事前に感謝します。
_不透明なデータ構造_は、 children
が、配列、フラグメント、単一要素、文字列リテラルなど、さまざまなものになる可能性があるという事実を指します。
_React.Children_には、さまざまな種類のchildren
_統一された方法で_操作できるいくつかのメソッドが含まれており、それらを操作する唯一の方法ではありません。
一部の子(1つ以上)が常に配列である場合(たとえば、「Preact」で行われるように)、props.childrenが正確にないのはなぜですか?
JSXに省略形があることを除けば、 children
は他のプロパティと同じです。 実際、次のように指定できます。
<Component children={...}/>
ReactがDOMを更新する必要がある場合、2つのプリミティブ値(文字列など)が同じであるかどうかよりも、2つの単一アイテム配列が同じであるかどうかを判断する方がはるかにコストがかかります。
そうは言っても、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
それでも、2番目の質問をもう一度したいと思います。
子が1つだけの場合、「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];
もう一度質問するのが少し面倒だと思われる場合は申し訳ありませんが、その設計上の決定の正確な理由を知りたいと思います。
私はあなたの質問の最初の部分であなたを助けることができてうれしいです! 残念ながら、単一の子が単一項目の配列として表されない理由については、_正確な_答えがありません。 ただし、(JSXの速記ではなく)通常の小道具として1人の子を有効に渡すことができることを指摘しようとしていました。これは、パフォーマンスに関連しているという仮説を誤って覆い隠してしまったためです。
@danburzoご回答ありがとうございます。
うーん、率直に言って、Reactチームの誰かがその設計決定の実際の理由を覚えていることを望みました...
Reactでの子供の小道具の取り扱いには本当に微妙な問題があるからです。
たとえば、次の例のコンポーネントTest1とTest2が同じように動作するかどうかをReact初心者に尋ねます(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の初心者に「children:PropTypes ....」はどのように見えるかを尋ねます。 私はそれを答えるのは簡単ではないと思います(少なくとも初心者にとっては)。
Reactチームへ:問題の設計決定の理由が実際にはわからない場合、または単に好みの問題である場合は、もちろん、この問題を自由に閉じてください。
不必要な配列の割り当てを避けるために、単一の子に配列を使用しないという決定がなされたと思います。
Reactでの子供の小道具の取り扱いには本当に微妙な問題があるからです。
通常、明示的なchildren
小道具の使用はお勧めしません。 ほとんどのユーザーは、 React.createElement
を直接呼び出す代わりにJSXも使用するため、言及した問題は通常は問題になりません。
@awearyご回答ありがとうございます
最も参考になるコメント
_不透明なデータ構造_は、
children
が、配列、フラグメント、単一要素、文字列リテラルなど、さまざまなものになる可能性があるという事実を指します。_React.Children_には、さまざまな種類の
children
_統一された方法で_操作できるいくつかのメソッドが含まれており、それらを操作する唯一の方法ではありません。JSXに省略形があることを除けば、
children
は他のプロパティと同じです。 実際、次のように指定できます。ReactがDOMを更新する必要がある場合、2つのプリミティブ値(文字列など)が同じであるかどうかよりも、2つの単一アイテム配列が同じであるかどうかを判断する方がはるかにコストがかかります。
そうは言っても、React.Childrenのドキュメントは少し拡張されるかもしれないと思いますが、それはreactjs /reactjs.orgリポジトリにログを記録する
この記事は物事を少し明確にするかもしれません、それは私のためになりました!