javascript - tutorial - react是什麼




React中的這三個點是做什麼的? (14)

... 在此React(使用JSX)代碼中做什麼?它叫什麼?

<Modal {...this.props} title='Modal heading' animation={false}>

用於簡單地傳遞多個屬性的擴展屬性

{... this.props}擁有this.props的屬性

將{...} Spread運算符與以下props一起使用

this.props = 
 { 
    firstName: 'Dan', 
    lastName: 'Abramov', 
    city: 'New York',
    country: 'USA' 
}

沒有{...}傳播

<Child 
  firstName={this.props.firstName}
  lastName={this.props.lastName}
  city={this.props.city}
  country={this.props.country}

> 

隨著{...}傳播

<Child { ...this.props } />

丹·阿布拉莫夫(Dan Abramov) 關於點差運算符 推文(Redux的創建者)


...此語法是ES6的一部分,不是只能在React中使用的語法,可以兩種不同的方式使用; 您可以在這篇文章中找到更多信息: https : //www.techiediaries.com/react-spread-operator-props-setstate/

您在問題中提到的是這樣的,讓我們假設這樣,

var component = <Component foo={x} bar={y} />;

使用散佈運算符,您可以像這樣將道具傳遞給組件。

var component = <Component />;
component.props.foo = x; // bad
component.props.bar = y;

JavaScript中的三個點是 傳播/休息運算符

點差運算符

擴展語法 允許在需要多個參數的地方擴展表達式。

myFunction(...iterableObj);

[...iterableObj, 4, 5, 6]

[...Array(10)]

休息參數

rest 參數語法用於參數數目可變的函數。

function(a, b, ...theArgs) {
  // ...
}

ES6中引入了數組的散佈/餘數運算符。 對於對象散佈/靜止屬性,有一個狀態2 proposal

TypeScript還支持傳播語法,並且可以將其轉換為ECMAScript的較早版本,而出現一些小 issues


三個點 ... 表示 擴展運算符 剩餘參數

它允許將數組表達式或字符串或任何可以 迭代的內容 擴展到期望零個或多個參數用於函數調用或數組元素的地方。

  • 合併兩個數組

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]

注意:傳播語法在復制數組時有效地深入了一層。 因此,如下面的示例所示,它可能不適合複製多維數組(與Object.assign()和spread語法相同)。

  • 將一個數組的值添加到特定索引處的另一個數組,例如3:

var arr1 = [4,5]
var arr2 = [1,2,3,...arr1,6]
console.log(arr2);	// [1, 2, 3, 4, 5, 6]

  • 用new調用構造函數時:

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}

請注意,obj2的 foo 屬性已被obj2覆蓋。

  • 作為剩餘參數語法,它使我們可以將不確定數量的參數表示為數組:

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

參考1

參考2


如您所知 ... 被稱為“ 擴展屬性” ,其名稱代表該名稱,它可以擴展表達式。

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} />

簡而言之, 可以說 這是一個 簡潔的 捷徑。


它只是為您在 JSX 中以不同的方式定義 道具

它在ES6中使用 ... 數組和對象運算符(尚不完全支持一個對象),因此,基本上,如果您已經定義了props,則可以將其傳遞給元素。

因此,在您的情況下,代碼應如下所示:

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} />
}

以下是React團隊關於JSX中的傳播算子的引文:

JSX傳播屬性如果您提前知道要放置在組件上的所有屬性,則使用JSX很容易:

var component = <Component foo={x} bar={y} />;

突變道具不好
如果您不知道要設置哪些屬性,則可能會在以後將它們添加到對像中:

var component = <Component />;
component.props.foo = x; // bad
component.props.bar = y; // also bad

這是一種反模式,因為這意味著我們要等到以後才能幫助您檢查正確的propTypes。 這意味著您的propTypes錯誤最終會導致隱秘的堆棧跟踪。

道具應該被認為是不變的。 將props對象突變到其他地方可能會導致意外的結果,因此理想情況下,此時將其凍結。

傳播屬性
現在,您可以使用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中的數組已經支持...運算符(或散佈運算符)。 還有一個ECMAScript建議書,涉及對象剩餘和傳播屬性。 我們利用這些受支持和正在開發的標準,以便在JSX中提供更簡潔的語法。


對於那些來自Python世界的人來說,JSX Spread屬性等同於 解壓縮參數列表 (Python ** -operator)。

我知道這是一個JSX問題,但是使用類比有時可以幫助使其更快。


簡而言之,這三個點是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]


這三個點表示ES6中的 擴展運算符 。 它使我們可以用Javascript做很多事情:

  1. 串聯數組

    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']
  2. 解構數組

      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']
  3. 梳理兩個物體

     function fun1(...params) { 
    
     }  

這三個點還有另一種用法,稱為 Rest參數 ,它可以將函數的所有參數作為一個數組。

  1. 函數參數作為數組

    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'}

這些被稱為點差。 顧名思義。 這意味著它將任何值放在這些數組或對像中。

如 :

 let a = [1, 2, 3]; let b = [...a, 4, 5, 6]; console.log(b); > [1, 2, 3, 4, 5, 6] 

這是React中也使用的es6的功能。 看下面的例子:

function Sum(x,y,z) {
   return x + y + z;
}
console.log(Sum(1,2,3)); //6

如果我們最多擁有3個參數,那麼這種方法很好,但是如果我們需要添加例如110個參數,該怎麼辦。 我們是否應該全部定義它們並一一添加? 當然,有一種更簡單的方法稱為SPREAD。 無需傳遞所有這些參數,而是編寫:

function (...numbers){} 

我們不知道我們有多少個參數,但是我們知道有很多參數。 基於es6,我們可以如下重寫上述功能,並使用它們之間的傳播和映射使它像一塊蛋糕一樣容易:

let Sum = (...numbers) => {
return numbers.reduce((prev, current) => prev + current );
}
console.log(Sum(1, 2, 3, 4, 5, 6, 7, 8, 9));//45

通常在React應用程序中傳遞道具。 通過這樣做,我們可以將狀態更改應用於子組件,而不管它是純組件還是不純組件(無狀態或有狀態)。 有時候,傳遞道具時最好的方法是傳遞單個屬性或整個屬性對象。 有了ES6中對數組的支持,我們得到了“ ...”符號,有了它,我們現在能夠實現將整個對像傳遞給孩子。

使用以下語法記錄將道具傳遞給孩子的典型過程:

var props = {};
props.foo = x;
props.bar = y;
var component = Component(props); // Where did my JSX go?

當道具的數量最小時,可以使用此方法,但是當道具的數量過多時,將變得難以管理。 當您不知道子組件內所需的屬性並且典型的JavaScript方法是簡單地設置這些屬性並在以後綁定到該對象時,就會出現此方法的問題。 這會導致propType檢查和隱式堆棧跟踪錯誤等問題無濟於事,並會導致調試延遲。 以下是此做法的示例以及不應該做的事情:

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'

但是不使用JSX Spread或JSX,因此要將其循環回方程式,我們現在可以執行以下操作:

var oldObj = { foo: 'hello', bar: 'world' };
var newObj = { ...oldObj, foo: 'hi' };
console.log(newObj.foo); // 'hi';
console.log(newObj.bar); // 'world';

“ ... props”中包含的屬性為foo:x,bar:y。 可以將其與其他屬性組合以使用以下語法覆蓋“ ... props”的屬性:

var ab = { ...a, ...b }; // merge(a, b)

另外,我們可以將其他屬性對象彼此復製或以這種方式組合它們:

function App1() {
  return <Greeting firstName="Ben" lastName="Hector" />;
}



function App2() {
  const props = {firstName: 'Ben', lastName: 'Hector'};
  return <Greeting {...props} />;
}

或像這樣合併兩個不同的對象(尚不能在所有react版本中使用):

let array = [1,2,3]
let array2 = [...array]
// array2 is now filled with the items from array

根據Facebook的react / docs網站,另一種解釋方式是:

如果您已經具有“ props”作為對象,並且想要在JSX中傳遞它,則可以使用“ ...”作為SPREAD運算符來傳遞整個props對象。 以下兩個示例是等效的:

// lets pass an object as props to a react component
let myParameters = {myKey: 5, myOtherKey: 7}
let component = <MyComponent {...myParameters}/>
// this is equal to <MyComponent myKey=5 myOtherKey=7 />

在構建通用容器時,傳播屬性會很有用。 但是,它們還可以通過輕鬆地將許多無關的道具傳遞給不需要它們的組件來使您的代碼混亂。 應謹慎使用此語法。


那是 財產傳播符號 。 它是在ES2018中添加的(用於數組/可迭代對象的版本更早於ES2015),但是隨著時間的流逝,它通過轉譯得到了支持(作為“ JSX傳播屬性 ”,即使您也可以在其他地方做到這一點,而不僅僅是屬性) 。

{...this.props} props 的“自己的”可枚舉屬性 散佈 為要創建的 Modal 元素上的離散屬性。 例如,如果 this.props 包含 a: 1b: 2 ,則

<Modal {...this.props} title='Modal heading' animation={false}>

將與

<Modal a={this.props.a} b={this.props.b} title='Modal heading' animation={false}>

但是它是動態的,因此包含了 props 中任何“自己的”屬性。

由於 childrenprops 的“自有”財產,因此傳播將包括它。 因此,如果出現此組件的組件具有子元素,則將它們傳遞給 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;
}


... (擴展運算符)用於反應:

提供一種將道具從父組件傳遞到子組件的巧妙方法。 例如,在父組件中給定這些道具,

this.props = {
  username: "danM",
  email: "[email protected]"
}

它們可以通過以下方式傳遞給孩子,

<ChildComponent {...this.props} />

與此類似

<ChildComponent username={this.props.username} email={this.props.email} />

但是更乾淨。





reactjs