Voulez-vous demander une fonctionnalité ou signaler un bogue ?
Juste des questions
Dans la documentation officielle React de React.Children, vous pouvez lire que this.props.children
est une "structure de données opaque".
Qu'est-ce que ça veut dire exactement?
Je pense qu'il y a en général trois possibilités pour la transparence de la structure de données de props.children
:
props.children
est ouvert et bien défini.Si cela était vrai, alors le terme «structure de données opaque» serait complètement faux.
Par conséquent, le "cas 1" n'est évidemment pas le cas.
props.children
n'est ouvert ou clair.Cela signifierait que chaque fois que vous utilisez props.children
vous DEVEZ TOUJOURS l'utiliser en combinaison avec React.Children
car React.Children
est le seul (mmmh, est-ce vraiment le seul?) qui connaît la structure de données réelle de props.children
.
Mais cela impliquerait qu'il ne devrait pas non plus être autorisé à utiliser
javascript
// This is used almost everywhere (even in the official React documentation)
<div>{this.props.children}</div>
ni
javascript
// This is often seen with the "Function as child" pattern
MyComponent.propTypes = {
children: PropTypes.func.isRequired,
};
Comme les deux exemples sont très courants, il semble que le «cas 2» ne soit évidemment pas non plus le cas.
props.children
sont ouverts et bien définis.Cela ouvrirait la possibilité que l'un ou même les deux exemples du «cas 2» soient valides.
Mais alors cela voudrait dire qu'il devrait y avoir une spécification exacte des aspects de props.children
sont bien et ouvertement définis et quels aspects sont vraiment opaques.
J'ai peut-être manqué quelque chose dans la documentation React, mais je pense que ce n'est pas vraiment spécifié ici, n'est-ce pas?
Pourquoi exactement props.children
au cas où il y aurait des enfants (un ou plusieurs) ne serait pas toujours un tableau (comme c'est le cas dans "Preact" par exemple)? Cela rendrait les choses tellement plus faciles, n'est-ce pas?
Merci d'avance pour les clarifications.
La _ structure de données opaque_ fait référence au fait que children
peut être beaucoup de choses: tableaux, fragments, éléments simples, littéraux de chaîne, etc.
_React.Children_ contient quelques méthodes qui vous permettent de travailler avec les différents types de children
_ d'une manière unifiée_, et ce n'est certainement pas le seul moyen d'interagir avec eux.
Pourquoi exactement n'est-ce pas props.children au cas où il y aurait des enfants (un ou plus) juste toujours un tableau (comme c'est le cas dans "Preact" par exemple)?
Mis à part le fait qu'il a un raccourci dans JSX, children
est une propriété comme les autres. En fait, vous pouvez le spécifier comme suit:
<Component children={...}/>
Lorsque React a besoin de mettre à jour le DOM, il serait beaucoup plus coûteux de dire si deux tableaux à un seul élément sont identiques que si deux valeurs primitives (par exemple des chaînes) sont identiques.
Cela étant dit, je pense que la documentation React.Children pourrait être un peu développée, mais c'est un problème à se connecter au référentiel reactjs / reactjs.org .
Cet article peut clarifier un peu les choses, il l'a fait pour moi!
Merci beaucoup @danburzo pour vos réponses et clarifications.
Après votre réponse, il est clair que j'ai complètement mal compris le mot «opaque».
La documentation React voulait juste dire que la structure de données de props.children
est un type d'union complètement bien défini et qu'elle varie dans sa représentation concrète (comme le font toujours les types d'union).
Je viens de trouver un problème plus ancien qui traitait exactement du même sujet - je me demande ce qui est arrivé à ces changements?!? (J'ai ouvert un problème sur reactjs.org => reactjs / reactjs.org # 914):
https://github.com/facebook/react/pull/6018/files/91223423410f107ff83a8a6ce3158c488247292f?short_path=ef51787#diff -ef51787305cfed62f6f564284762d4de
Néanmoins, je voudrais encore poser la deuxième question:
Pourquoi "props.children" n'est-il PAS un tableau au cas où il y aurait exactement UN enfant (cela semble vraiment une violation du principe du moindre étonnement si vous ne connaissez pas l'arrière-plan => si le nom est "children" ou "items" ou "jetons" vous attendez normalement une collection)?
Est-ce vraiment pour des raisons de performances? Je ne vois pas vraiment que le calcul de "checkResult" ci-dessous prend autant de temps:
const
child1 = ...,
child2 = ...,
child1IsArray = Array.isArray(child1),
child2IsArray = Array.isArray(child2),
checkResult = child1IsArray && child2IsArray
&& child1.length === 1 && child2.length === 1
&& child1[0] === child2[0];
Désolé si demander à nouveau semble un peu ennuyeux - mais j'aimerais vraiment connaître la raison exacte de cette décision de conception ....
Je suis heureux de pouvoir vous aider avec la première partie de votre question! Malheureusement, quant à la raison pour laquelle les enfants uniques ne sont pas représentés comme un tableau à un seul élément, je n'ai pas de réponse _exact_. Cependant, j'essayais de souligner que vous pouvez toujours valablement passer un seul enfant comme accessoire normal (plutôt que le raccourci JSX), un fait que j'ai accidentellement obscurci avec mon hypothèse selon laquelle il est lié à la performance.
@danburzo Merci encore pour votre réponse.
Mmh, franchement, j'espérais que quelqu'un de l'équipe React se souviendrait peut-être de la raison réelle de cette décision de conception ...
Parce qu'il y a vraiment des problèmes subtils avec la manipulation des accessoires enfants dans React.
Par exemple, demandez à un débutant React si les composants Test1 et Test2 dans l'exemple suivant se comportent de la même manière (vous - en tant que pro React - savez que la réponse est "non" => Test2 avertira DEV des clés manquantes tandis que Test1 le fera non - mais est-ce vraiment ce à quoi vous vous attendriez si vous étiez un débutant?!?)
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')
);
Au fait: si Test2 était autorisé, cela aurait des avantages subtils en termes de performances si vous implémentiez des remplacements createElement
- comme une fonction hyperscript par exemple.
Un autre exemple: demandez à un débutant de React à quoi ressemblerait "children: PropTypes ...." si l'exigence est que tous les enfants doivent satisfaire une certaine condition. Je pense que ce ne serait pas facile de répondre (du moins pour un débutant).
À l'équipe React: Si les raisons de la décision de conception en question ne sont pas vraiment connues ou n'étaient peut-être qu'une question de goût, alors bien sûr, n'hésitez pas à clore ce problème.
Je suppose que la décision de ne pas utiliser de tableau pour un seul enfant a été prise pour éviter les allocations de tableau inutiles.
Parce qu'il y a vraiment des problèmes subtils avec la manipulation des accessoires enfants dans React.
Nous ne recommandons généralement pas d'utiliser une propriété children
explicite. La plupart des utilisateurs utilisent également JSX au lieu d'appeler directement React.createElement
, donc les problèmes que vous avez mentionnés ne sont généralement pas un problème.
@aweary Merci pour votre réponse
Commentaire le plus utile
La _ structure de données opaque_ fait référence au fait que
children
peut être beaucoup de choses: tableaux, fragments, éléments simples, littéraux de chaîne, etc._React.Children_ contient quelques méthodes qui vous permettent de travailler avec les différents types de
children
_ d'une manière unifiée_, et ce n'est certainement pas le seul moyen d'interagir avec eux.Mis à part le fait qu'il a un raccourci dans JSX,
children
est une propriété comme les autres. En fait, vous pouvez le spécifier comme suit:Lorsque React a besoin de mettre à jour le DOM, il serait beaucoup plus coûteux de dire si deux tableaux à un seul élément sont identiques que si deux valeurs primitives (par exemple des chaînes) sont identiques.
Cela étant dit, je pense que la documentation React.Children pourrait être un peu développée, mais c'est un problème à se connecter au référentiel reactjs / reactjs.org .
Cet article peut clarifier un peu les choses, il l'a fait pour moi!