このReact(JSXを使用した)コードで...
は何をしているのでしょうか、そしてそれは何と呼ばれていますか?
<Modal {...this.props} title='Modal heading' animation={false}>
それがプロパティスプレッド表記です。 ES2018で追加されましたが、Reactプロジェクトではトランスピュレーションを介して長い間サポートされていました(属性だけでなく他の場所でも使用できますが、「JSXスプレッド属性」として)。
{...this.props}
展開作成中のprops
要素の個別のプロパティとしてのModal
内の「独自の」プロパティたとえば、this.props
にa: 1
とb: 2
が含まれている場合、
<Modal {...this.props} title='Modal heading' animation={false}>
と同じになります
<Modal a={this.props.a} b={this.props.b} title='Modal heading' animation={false}>
しかしそれは動的なので、props
に含まれる "独自の"プロパティはすべて含まれます。
children
はprops
では「独自の」プロパティであるため、spreadにはそれが含まれます。そのため、これが現れるコンポーネントに子要素がある場合、それらはModal
に渡されます。開始タグと終了タグの間に子要素を配置することは、開始タグ内にchildren
プロパティを配置するための単なる構文上の砂糖です。例:
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>
スプレッド記法は、そのユースケースだけでなく、既存のオブジェクトのほとんどの(またはすべての)プロパティを持つ新しいオブジェクトを作成するのに便利です。状態を変更することはできません。直接:
this.setState(prevState => {
return {foo: {...prevState.foo, a: "updated"}};
});
これはthis.state.foo
をfoo
と同じすべてのプロパティを持つ新しいオブジェクトに置き換えます。ただし、a
プロパティは"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;
}
あなたが知っているように...
はSpread Attributesと呼ばれ、その名前はそれが表すことで式を拡張することができます。
var parts = ['two', 'three'];
var numbers = ['one', ...parts, 'four', 'five']; // ["one", "two", "three", "four", "five"]
そしてこの場合(私はそれを単純化するつもりです)。
//just assume we have an object like this:
var person= {
name: 'Alex',
age: 35
}
この:
<Modal {...person} title='Modal heading' animation={false} />
等しい
<Modal name={person.name} age={person.age} title='Modal heading' animation={false} />
だから、要するに、それはきちんとした近道です、私たちは言うことができます.
JavaScriptの3つのドットは スプレッド/レスト演算子 です。
スプレッド演算子
spread構文 を使用すると、複数の引数が必要な場所で式を展開できます。
myFunction(...iterableObj);
[...iterableObj, 4, 5, 6]
[...Array(10)]
休憩パラメータ
rest parameter構文は、可変数の引数を持つ関数に使用されます。
function(a, b, ...theArgs) {
// ...
}
配列のスプレッド/レスト演算子はES6で導入されました。 State 2 提案 object spread/restのプロパティがあります。
TypeScriptはスプレッド構文もサポートしており、マイナー issues を使用してそれを古いバージョンのECMAScriptに変換できます。
ES6では、3つの点は スプレッド演算子 を表します。それは私達がJavascriptでかなりの数のことをすることを可能にします:
配列をコピーする
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']
配列を再構築する
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']
配列としての関数引数
function fun1(...params) {
}
上記は休止パラメータとして知られており、関数に渡される値の数を制限しません。ただし、引数は同じ型でなければなりません。
2つのオブジェクトをとかしています
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'}
これは、Reactでも使用されているes6の機能です。以下の例を見てください。
function Sum(x,y,z) {
return x + y + z;
}
console.log(Sum(1,2,3)); //6
最大3つのパラメータがある場合はこの方法で問題ありませんが、たとえば110個のパラメータを追加する必要がある場合はどうなりますか。それらすべてを定義して、それらを1つずつ追加する必要がありますか?!もちろん、SPREADと呼ばれるより簡単な方法があります。
function (...numbers){}
パラメータがいくつあるかはわかりませんが、それらのヒープがあることがわかります。ケーキの
let Sum = (...numbers) => {
return numbers.reduce((prev, current) => prev + current );
}
console.log(Sum(1, 2, 3, 4, 5, 6, 7, 8, 9));//45
それは props を _ jsx _ で異なる方法で定義しているだけです!
ES6では...
配列とオブジェクト演算子(オブジェクトはまだ完全にはサポートされていません)を使用しているので、基本的にすでにプロップを定義していれば、この方法で要素に渡すことができます。
だからあなたの場合は、コードは次のようになります。
function yourA() {
const props = {name='Alireza', age='35'};
<Modal {...props} title='Modal heading' animation={false} />
}
だからあなたが定義した小道具は今分離され、必要なら再利用することができます。
それはに等しいです:
function yourA() {
<Modal name='Alireza' age='35' title='Modal heading' animation={false} />
}
これらは、JSXのスプレッド演算子に関するReactチームからの引用です。
JSXスプレッド属性コンポーネントに配置したいすべてのプロパティを事前に知っていれば、JSXを使用するのは簡単です。
var component = <Component foo={x} bar={y} />;
変な小道具は悪いです
どのプロパティを設定したいのかわからない場合は、後でそれらをオブジェクトに追加したくなるかもしれません。
var component = <Component />;
component.props.foo = x; // bad
component.props.bar = y; // also bad
これはアンチパターンです。これは、後で正しいpropTypeをチェックする手助けができないことを意味するためです。これはあなたのpropTypes エラーが不可解なスタックトレースで終わることを意味します。
小道具は不変と見なすべきです。他の場所で小道具オブジェクトを変更すると、予期しない結果が生じる可能性があるので、理想的にはこの時点でそれはフリーズしたオブジェクトになります。
スプレッド属性
これで、スプレッド属性と呼ばれるJSXの新機能を使用できます。
var props = {};
props.foo = x;
props.bar = y;
var component = <Component {...props} />;
渡したオブジェクトのプロパティは、コンポーネントの小道具にコピーされます。
これを複数回使用することも、他の属性と組み合わせることもできます。指定の順序は重要です。後の属性は前のものを上書きします。
var props = { foo: 'default' };
var component = <Component {...props} foo={'override'} />;
console.log(component.props.foo); // 'override'
奇妙な表記法とは何ですか?
...演算子(または展開演算子)は、ES6の配列ですでにサポートされています。 Object Rest and Spread PropertiesについてのECMAScriptの提案もあります。 JSXでより明確な構文を提供するために、これらのサポートされ開発されている標準を利用しています。
Pythonの世界から来た人たちにとって、JSX Spread Attributesは Unpacking Argument Lists (Python **
-演算子)と同等です。
私はこれがJSXの問題であることを認識していますが、類推を扱うことは時々速くそれを手助けするのを助けます。
...
(拡散演算子)は、次のものに反応して使用されます。
親から子コンポーネントに小道具を渡すためのきちんとした方法を提供します。例えば、これらの小道具を親コンポーネントに指定すると、
this.props = {
username: "danM",
email: "[email protected]"
}
彼らは次のように子供に渡されることができました、
<ChildComponent {...this.props} />
これはこれに似ています
<ChildComponent username={this.props.username} email={this.props.email} />
しかしずっときれい。
3つのドット(...)
は拡散演算子と呼ばれます。これは概念的にはES6配列拡散演算子であるJSX に似ており、JSXでより明確な構文を提供するためにこれらのサポートおよび開発標準を利用します
オブジェクト初期化子内のSpreadプロパティは、提供されたオブジェクトから新しく作成されたオブジェクトに、列挙可能なプロパティをコピーします。
let n = { x, y, ...z }; n; // { x: 1, y: 2, a: 3, b: 4 }
参照:
1) https://github.com/sebmarkbage/ecmascript-rest-spread#spread-properties
3つのドット...
は を表します - // / - 休憩パラメータ 、
これにより、配列式、文字列、またはiterating)になり得るものすべてを、関数呼び出し用のゼロ個以上の引数または配列用の要素が必要な場所に展開することができます。
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]
注:配列をコピーしている間、スプレッド構文は事実上1レベル深くなります。したがって、次の例に示すように多次元配列をコピーするのには適していません(Object.assign()および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}
Obj1のfoo
プロパティが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
注:スプレッド構文の場合(スプレッドプロパティの場合を除く)は反復可能なオブジェクトにのみ適用できます。したがって、次のようにエラーが発生します
var obj = {'key1': 'value1'};
var array = [...obj]; // TypeError: obj is not iterable
つまり、3つのドットはES6(ES2015)のスプレッド演算子です。スプレッド演算子はすべてのデータを取得します。
let a = [1, 2, 3, 4];
let b = [...a, 4, 5, 6];
let c = [7,8,...a];
console.log(b); 結果を出力する[1,2,3,4,5,6]
console.log(c); 結果を返す[7,8,1,2,3,4]
複数のプロパティを簡単な方法で渡すために使用されるスプレッド属性
{... this.props}はthis.propsのプロパティを保持しています
{...}スプレッド演算子と以下の支柱の使用
this.props = { firstName: 'Dan', lastName: 'Abramov', city: 'New York', country: 'USA' }
なし{...} Spread
<Child firstName={this.props.firstName} lastName={this.props.lastName} city={this.props.city} country={this.props.country} >
With {...} Spread
<Child { ...this.props } />
通常、スプレッド演算子と呼ばれ、必要な場所に展開するために使用されます
例
const SomeStyle = {
margin:10,
background:#somehexa
}
スプレッド演算子 スプレッド構文 が必要な場合は、これを使用できます。
それは、呼ばれる拡散演算子です。例えば、 let hello = {name: ''、msg: ''} let hello1 = {... hello} これで、helloオブジェクトのプロパティはhello1にコピーされます。
Reactアプリケーションで小道具を渡すのが一般的なやり方です。これを行うことで、PureまたはImpure(ステートレスまたはステートフル)のいずれであるかにかかわらず、子コンポーネントに状態の変更を適用することができます。小道具を渡すときに最善の方法は、単一のプロパティまたはプロパティのオブジェクト全体を渡すことです。 ES6で配列をサポートすることで "..."という表記が与えられ、これでオブジェクト全体を子に渡すことができるようになりました。
小道具を子供に渡す典型的なプロセスは、次の構文で説明されています。
var component = <Component foo={x} bar={y} />;
小道具の数が最小の場合はこれを使用するのが問題ありませんが、小道具の数が多すぎると管理できなくなります。このメソッドの問題は、子コンポーネント内で必要なプロパティがわからない場合に発生します。通常のJavaScriptメソッドでは、これらのプロパティを簡単に設定して後でオブジェクトにバインドします。これはpropTypeチェックと暗号スタックトレースエラーの問題を引き起こしますが、それらは役に立ちませんしデバッグの遅延を引き起こします。以下はこのプラクティスの例であり、してはいけないことです。
var component = <Component />;
component.props.foo = x; // bad
component.props.bar = y;
これと同じ結果を得ることができますがこれを行うことによってより適切な成功を収めます。
var props = {};
props.foo = x;
props.bar = y;
var component = Component(props); // Where did my JSX go?
しかし、JSX spreadやJSXを使用しないで、これを式にループバックして、次のようなことができるようになります。
var props = {};
props.foo = x;
props.bar = y;
var component = <Component {...props} />;
"... props"に含まれるプロパティは、foo:x、bar:yです。これを他の属性と組み合わせて、この構文を使用して "... props"のプロパティをオーバーライドできます。
var props = { foo: 'default' };
var component = <Component {...props} foo={'override'} />;
console.log(component.props.foo); // 'override'
さらに、他のプロパティオブジェクトを互いにコピーしたり、次のように組み合わせたりできます。
var oldObj = { foo: 'hello', bar: 'world' };
var newObj = { ...oldObj, foo: 'hi' };
console.log(newObj.foo); // 'hi';
console.log(newObj.bar); // 'world';
またはこのように2つの異なるオブジェクトをマージします(これはすべての反応バージョンでまだ利用可能ではありません):
var ab = { ...a, ...b }; // merge(a, b)
これを説明する別の方法は、Facebookのreact/docsサイトによると、次のとおりです。
オブジェクトとして "props"が既にあり、それをJSXで渡したい場合は、 "..."をSPREAD演算子として使用してpropsオブジェクト全体を渡すことができます。次の2つの例は同等です。
function App1() {
return <Greeting firstName="Ben" lastName="Hector" />;
}
function App2() {
const props = {firstName: 'Ben', lastName: 'Hector'};
return <Greeting {...props} />;
}
スプレッド属性は、一般的なコンテナを構築するときに役立ちます。ただし、それらを気にしないコンポーネントに多くの無関係な小道具を渡しやすくすることで、コードが面倒になることもあります。この構文は控えめに使用してください。
...の意味は、コード内での使用場所によって異なります。
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]