Que fait le ...
dans ce code React (utilisant JSX) et comment s'appelle-t-il?
<Modal {...this.props} title='Modal heading' animation={false}>
C'est propriété propagation notation . Il a été ajouté dans ES2018, mais est depuis longtemps pris en charge dans les projets React via la transpilation (en tant qu '"attributs JSX spread", même si vous pouvez le faire ailleurs, pas seulement les attributs).
{...this.props}
étale les propriétés "propres" dans props
en tant que propriétés discrètes sur l'élément Modal
que vous créez. Par exemple, si this.props
contenait a: 1
et b: 2
, alors
<Modal {...this.props} title='Modal heading' animation={false}>
serait la même chose que
<Modal a={this.props.a} b={this.props.b} title='Modal heading' animation={false}>
Mais c'est dynamique, donc toutes les propriétés "propres" dans props
sont incluses.
Puisque children
est une propriété "propre" dans props
, spread l’inclura. Donc, si le composant où cela apparaît a des éléments enfants, ils seront passés à Modal
. Mettre des éléments enfants entre la balise d'ouverture et les balises de fermeture est simplement du sucre syntaxique - le bon type - pour mettre une propriété children
dans la balise d'ouverture. Exemple:
class Example extends React.Component {
render() {
const { className, children } = this.props;
return (
<div className={className}>
{children}
</div>
);
}
}
ReactDOM.render(
[
<Example className="first">
<span>Child in first</span>
</Example>,
<Example className="second" children={<span>Child in second</span>} />
],
document.getElementById("root")
);
.first {
color: green;
}
.second {
color: blue;
}
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
La notation Spread est pratique non seulement pour ce cas d'utilisation, mais pour créer un nouvel objet avec la plupart (ou toutes les) propriétés d'un objet existant - ce qui est souvent le cas lorsque vous mettez à jour un état, car vous ne pouvez pas modifier cet état. directement:
this.setState(prevState => {
return {foo: {...prevState.foo, a: "updated"}};
});
Cela remplace this.state.foo
par un nouvel objet ayant les mêmes propriétés que foo
à l'exception de la propriété a
qui devient "updated"
:
const obj = {
foo: {
a: 1,
b: 2,
c: 3
}
};
console.log("original", obj.foo);
// Creates a NEW object and assigns it to `obj.foo`
obj.foo = {...obj.foo, a: "updated"};
console.log("updated", obj.foo);
.as-console-wrapper {
max-height: 100% !important;
}
Comme vous le savez, les ...
sont appelés Attributs de propagation dont le nom représente une extension.
var parts = ['two', 'three'];
var numbers = ['one', ...parts, 'four', 'five']; // ["one", "two", "three", "four", "five"]
Et dans ce cas (je vais le simplifier).
//just assume we have an object like this:
var person= {
name: 'Alex',
age: 35
}
Ce:
<Modal {...person} title='Modal heading' animation={false} />
est égal à
<Modal name={person.name} age={person.age} title='Modal heading' animation={false} />
En bref, c'est un soigné raccourci, nous pouvons dire.
Les trois points en JavaScript sont spread/rest operator.
Opérateur Spread
La syntaxe de propagation } permet de développer une expression à des endroits où plusieurs arguments sont attendus.
myFunction(...iterableObj);
[...iterableObj, 4, 5, 6]
[...Array(10)]
Paramètres de repos
La syntaxe de paramètre reste est utilisée pour les fonctions avec un nombre variable d'arguments.
function(a, b, ...theArgs) {
// ...
}
L'opérateur de propagation/repos pour les matrices a été introduit dans ES6. Il existe un état 2 proposition pour les propriétés d'étalement/de repos d'objet.
TypeScript prend également en charge la syntaxe de propagation et peut transpiler cela dans des versions plus anciennes d'ECMAScript avec mineur problèmes .
Les trois points représentent l'opérateur Spread Operator dans ES6. Cela nous permet de faire pas mal de choses en Javascript:
Copier un tableau
var shooterGames = ['Call of Duty', 'Far Cry', 'Resident Evil' ];
var racingGames = ['Need For Speed', 'Gran Turismo', 'Burnout'];
var games = [...shooterGames, ...racingGames];
console.log(games) // ['Call of Duty', 'Far Cry', 'Resident Evil', 'Need For Speed', 'Gran Turismo', 'Burnout']
Destructuration d'un tableau
var shooterGames = ['Call of Duty', 'Far Cry', 'Resident Evil' ];
var [first, ...remaining] = shooterGames;
console.log(first); //Call of Duty
console.log(remaining); //['Far Cry', 'Resident Evil']
Arguments de fonction sous forme de tableau
function fun1(...params) {
}
Ce qui précède est appelé paramètre de repos et ne limite pas le nombre de valeurs transmises à une fonction. Cependant, les arguments doivent être du même type.
Combiner deux objets
var myCrush = {
firstname: 'Selena',
middlename: 'Marie'
};
var lastname = 'my last name';
var myWife = {
...myCrush,
lastname
}
console.log(myWife); // {firstname: 'Selena',
// middlename: 'Marie',
// lastname: 'my last name'}
C'est une caractéristique de es6 qui est également utilisée dans React. Regardez l'exemple ci-dessous:
function Sum(x,y,z) {
return x + y + z;
}
console.log(Sum(1,2,3)); //6
Cette méthode convient si nous n’avons pas plus de 3 paramètres, mais qu’il faut ajouter par exemple 110 paramètres. Devrions-nous les définir tous et les ajouter un par un?! Bien sûr, il existe un moyen plus facile de faire ce que l’on appelle SPREAD .
function (...numbers){}
Nous n'avons aucune idée du nombre de paramètres dont nous disposons mais nous savons qu'il existe des tas de ceux-ci. :
let Sum = (...numbers) => {
return numbers.reduce((prev, current) => prev + current );
}
console.log(Sum(1, 2, 3, 4, 5, 6, 7, 8, 9));//45
Il suffit de définir les accessoires de manière différente dansJSXpour vous!
Il utilise ...
tableau et opérateur d'objet dans ES6 (le premier objet n'est pas encore complètement supporté), donc si vous définissez déjà vos accessoires, vous pouvez le transmettre à votre élément de cette façon.
Donc, dans votre cas, le code devrait ressembler à ceci:
function yourA() {
const props = {name='Alireza', age='35'};
<Modal {...props} title='Modal heading' animation={false} />
}
les accessoires que vous avez définis, maintenant séparés, peuvent être réutilisés si nécessaire.
C'est égal à:
function yourA() {
<Modal name='Alireza' age='35' title='Modal heading' animation={false} />
}
Voici les citations de l'équipe de React à propos de l'opérateur de propagation dans JSX:
Attributs de propagation JSX Si vous connaissez toutes les propriétés que vous souhaitez placer sur un composant à l’avance, il est facile d’utiliser JSX:
var component = <Component foo={x} bar={y} />;
La mutation des accessoires est mauvaise
Si vous ne savez pas quelles propriétés vous souhaitez définir, vous pouvez être tenté de les ajouter ultérieurement à l'objet:
var component = <Component />;
component.props.foo = x; // bad
component.props.bar = y; // also bad
Ceci est un anti-modèle parce que cela signifie que nous ne pouvons pas vous aider à vérifier les bonnes propTypes jusqu'à bien plus tard. Cela signifie que vos propTypes les erreurs se retrouvent avec une trace de pile cryptique.
Les accessoires doivent être considérés comme immuables. Mutation de l'objet accessoires ailleurs pourrait causer des conséquences inattendues alors idéalement, il être un objet gelé à ce stade.
Attributs de propagation
Maintenant, vous pouvez utiliser une nouvelle fonctionnalité de JSX appelée attributs répartis:
var props = {};
props.foo = x;
props.bar = y;
var component = <Component {...props} />;
Les propriétés de l'objet que vous transmettez sont copiées dans le fichier les accessoires du composant.
Vous pouvez l'utiliser plusieurs fois ou le combiner avec d'autres attributs . L'ordre des spécifications est important. Les attributs ultérieurs remplacent les précédents.
var props = { foo: 'default' };
var component = <Component {...props} foo={'override'} />;
console.log(component.props.foo); // 'override'
C'est quoi cette notation ... bizarre?
L'opérateur ... (ou l'opérateur de propagation) est déjà pris en charge pour les matrices dans ES6. Il y a aussi une proposition ECMAScript pour les propriétés de l'objet Reste et Spread. Étaient en tirant parti de ces normes et en élaborant des normes dans l’ordre. fournir une syntaxe de nettoyage dans JSX.
Pour ceux qui viennent du monde Python, les attributs JSX Spread sont équivalents à Unpacking Argument Lists (l'opérateur Python **
-).
Je suis conscient que c'est une question JSX, mais travailler avec des analogies aide parfois à l'obtenir plus rapidement.
Le ...
(opérateur de propagation) est utilisé pour réagir à:
fournit un moyen astucieux de passer les accessoires des composants parent aux enfants. par exemple, étant donné ces accessoires dans un composant parent,
this.props = {
username: "danM",
email: "[email protected]"
}
ils pourraient être transmis de la manière suivante à l'enfant,
<ChildComponent {...this.props} />
qui est semblable à ceci
<ChildComponent username={this.props.username} email={this.props.email} />
mais bien plus propre.
Les trois points (...)
sont appelés opérateurs d’extension, ce qui est conceptuellement similaire à l’opérateur d’extension de matrice ES6, JSX.
Les propriétés de propagation dans les initialiseurs d'objet copient leur propre énumérable propriétés d'un objet fourni sur le nouvel objet créé.
let n = { x, y, ...z }; n; // { x: 1, y: 2, a: 3, b: 4 }
Référence:
1) https://github.com/sebmarkbage/ecmascript-rest-spread#spread-properties
Trois points ...
représente Opérateurs d'étalement ou Paramètres de repos ,
Il permet de développer une expression de tableau, une chaîne de caractères ou tout ce qui peut être iterating à des emplacements où zéro argument ou plus pour les appels de fonction ou les éléments de tableau sont attendus.
var arr1 = [1,2,3];
var arr2 = [4,5,6];
arr1 = [...arr1, ...arr2];
console.log(arr1); //[1, 2, 3, 4, 5, 6]
var arr = [1, 2, 3];
var arr2 = [...arr];
console.log(arr); //[1, 2, 3]
Remarque: La syntaxe de propagation s'étend effectivement d'un niveau lors de la copie d'un tableau. Par conséquent, il peut être inapproprié de copier des tableaux multidimensionnels, comme le montre l'exemple suivant (il en va de même avec Object.assign () et la syntaxe spread).
var arr1 = [4,5]
var arr2 = [1,2,3,...arr1,6]
console.log(arr2); // [1, 2, 3, 4, 5, 6]
var dateFields = [1970, 0, 1]; // 1 Jan 1970
var d = new Date(...dateFields);
console.log(d);
var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };
var clonedObj = { ...obj1 };
console.log(clonedObj); //{foo: "bar", x: 42}
var mergedObj = { ...obj1, ...obj2 };
console.log(mergedObj); //{foo: "baz", x: 42, y: 13}
Notez que la propriété foo
de obj1 a été remplacée par la propriété obj2 foo
function sum(...theArgs) {
return theArgs.reduce((previous, current) => {
return previous + current;
});
}
console.log(sum(1, 2, 3)); //6
console.log(sum(1, 2, 3, 4)); //10
Remarque: la syntaxe de propagation (autre que dans le cas de propriétés de propagation) ne peut être appliquée qu'aux objets itérables:
var obj = {'key1': 'value1'};
var array = [...obj]; // TypeError: obj is not iterable
En bref, les trois points ... est un opérateur étendu dans ES6 (ES2015). L'opérateur de propagation va chercher toutes les données.
let a = [1, 2, 3, 4];
let b = [...a, 4, 5, 6];
let c = [7,8,...a];
console.log (b); donne le résultat [1,2,3,4,5,6]
console.log (c); donne le résultat [7,8,1,2,3,4]
Son opérateur de propagation appelé Par exemple, Let hello = {name: '', msg: ''} Let hello1 = {... hello} Maintenant, les propriétés d'objet Hello sont copiées dans hello1. .
Il est courant de transmettre des accessoires dans une application React. Ce faisant, nous pouvons appliquer des changements d’état au composant enfant, qu’il soit pur ou impur (sans état ou avec état). Il arrive parfois que la meilleure approche, lors du passage d'accessoires, consiste à transmettre des propriétés singulières ou un objet entier de propriétés. Avec la prise en charge des tableaux dans ES6, nous avons reçu la notation "..." qui nous permet désormais de passer un objet entier à un enfant.
Le processus typique de transmission d'accessoires à un enfant est noté avec cette syntaxe:
var component = <Component foo={x} bar={y} />;
Cela convient très bien lorsque le nombre d'accessoires est minime, mais devient ingérable lorsque le nombre d'accessoires devient trop élevé. Un problème avec cette méthode se produit lorsque vous ne connaissez pas les propriétés requises dans un composant enfant et que la méthode JavaScript typique consiste à définir simplement ces propriétés et à les lier ultérieurement à l'objet. Cela pose des problèmes avec la vérification propType et les erreurs de trace de pile cryptiques qui ne sont pas utiles et qui retardent le débogage. Voici un exemple de cette pratique et de ce qu'il ne faut pas faire:
var component = <Component />;
component.props.foo = x; // bad
component.props.bar = y;
Ce même résultat peut être atteint, mais avec un succès plus approprié:
var props = {};
props.foo = x;
props.bar = y;
var component = Component(props); // Where did my JSX go?
Mais n'utilisant ni JSX spread, ni JSX, pour revenir à l'équation, nous pouvons maintenant faire quelque chose comme ceci:
var props = {};
props.foo = x;
props.bar = y;
var component = <Component {...props} />;
Les propriétés incluses dans "... props" sont foo: x, bar: y. Ceci peut être combiné avec d'autres attributs pour remplacer les propriétés de "... props" en utilisant cette syntaxe:
var props = { foo: 'default' };
var component = <Component {...props} foo={'override'} />;
console.log(component.props.foo); // 'override'
De plus, nous pouvons copier d'autres objets de propriétés les uns sur les autres ou les combiner de cette manière:
var oldObj = { foo: 'hello', bar: 'world' };
var newObj = { ...oldObj, foo: 'hi' };
console.log(newObj.foo); // 'hi';
console.log(newObj.bar); // 'world';
Ou fusionner deux objets différents comme celui-ci (ceci n'est pas encore disponible dans toutes les versions de réaction):
var ab = { ...a, ...b }; // merge(a, b)
Une autre façon d’expliquer cela, selon le site react/docs de Facebook, est la suivante:
Si vous avez déjà "props" en tant qu'objet et que vous souhaitez le transmettre au format JSX, vous pouvez utiliser "..." en tant qu'opérateur SPREAD pour transmettre l'ensemble de l'objet props. Les deux exemples suivants sont équivalents:
function App1() {
return <Greeting firstName="Ben" lastName="Hector" />;
}
function App2() {
const props = {firstName: 'Ben', lastName: 'Hector'};
return <Greeting {...props} />;
}
Les attributs de propagation peuvent être utiles lorsque vous créez des conteneurs génériques. Cependant, ils peuvent également rendre votre code compliqué en facilitant le transfert d'un grand nombre d'accessoires non pertinents à des composants qui ne s'en soucient pas. Cette syntaxe doit être utilisée avec parcimonie.
Attributs de propagation utilisés pour transmettre les propriétés multiples de manière simple} _
{... this.props} détient la propriété de this.props
_ {Utilisation de l'opérateur {...} Spread avec les accessoires ci-dessous}
this.props = { firstName: 'Dan', lastName: 'Abramov', city: 'New York', country: 'USA' }
Sans {...} Spread
<Child firstName={this.props.firstName} lastName={this.props.lastName} city={this.props.city} country={this.props.country} >
Avec {...} Spread
<Child { ...this.props } />
Dan Abramov's Tweet sur l'opérateur Spread (créateur de Redux) https://Twitter.com/dan_abramov/status/694519379191545856?lang=fr
La signification de ... dépend de l'endroit où vous l'utilisez dans le code,
const numbers = [1,2,3];
const newNumbers = [...numbers, 4];
console.log(newNumbers) //prints [1,2,3,4]
const person = {
name: 'Max'
};
const newPerson = {...person, age:28};
console.log(newPerson); //prints {name:'Max', age:28}
const filter = (...args) => {
return args.filter(el => el ===1);
}
console.log(filter(1,2,3)); //prints [1]