Что делают эти три точки в React?

559

Что делает ... в этом реакторе (с использованием JSX) и что он называется?

<Modal {...this.props} title='Modal heading' animation={false}>
  • 1
    Theres - простое и понятное чтение, доступное здесь по распространенному синтаксису: codeburst.io/javascript-es6-the-spread-syntax-f5c35525f754
  • 0
    ПРИМЕЧАНИЕ: оператор ... ведет себя по-разному в разных контекстах. В этом контексте это оператор «распространения», описанный ниже @TJ Crowder. В другом контексте это также может быть оператор rest, описанный ниже @Tomas Nikodym.
Теги:
react-bootstrap

17 ответов

661
Лучший ответ

Это свойство распространяется нотации. Он был добавлен в 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, спред будет включать его. Так что, если компонент, где это появляется, имеет дочерние элементы, они будут переданы в 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="/react.production.min.js"></script>
<script src="/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;
}
  • 2
    Благодарю. Это видео также помогло мне youtu.be/1INe_jCWq1Q
  • 1
    Имеет ли положить дочерний элемент между открывающим и закрывающим тегами переопределения children собственность или они объединены?
Показать ещё 1 комментарий
214

Как вы знаете, ... называются Атрибуты распространения, которые оно представляет, позволяет расширять выражение.

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

Короче говоря, это короткое сокращение аккуратное.

30

Три точки в JavaScript - это оператор распространения/отдыха.

Оператор распространения

синтаксис распространения позволяет расширять выражение в местах, где ожидаются несколько аргументов.

myFunction(...iterableObj);

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

[...Array(10)]

Параметры останова

Параметр синтаксиса rest используется для функций с переменным числом аргументов.

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

Оператор распространения/отдыха для массивов был введен в ES6. Там представлено предложение 2 для свойств объекта/свойства объекта.

TypeScript также поддерживает синтаксис распространения и может перевести его в более старые версии ECMAScript с небольшим issues.

26

Три точки представляют Оператор Распространения в 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) { 
    
     }  
    

Вышеупомянутое известно как остальные параметры и не ограничивает количество значений, передаваемых в функцию. Однако аргументы должны быть одного типа.

  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'}
    
  • 5
    Это отличный ответ из-за всех наглядных примеров для каждого варианта использования. Спасибо, что нашли время написать все это.
  • 0
    Упомяните остальные параметры перед примером для большей ясности
25

Это особенность es6, которая также используется в React. Посмотрите пример ниже:

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
11

Это просто определение реквизита в 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} />
}

Вот цитаты из команды 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 заканчиваются загадочной трассировкой стека.

Реквизит следует считать неизменным. Мутирование объекта реквизита в другом месте может привести к непредвиденным последствиям, поэтому в идеале это будет замороженный объект на данном этапе.

Атрибуты распространения
Теперь вы можете использовать новую функцию 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.

11

Для тех, кто пришел из мира Python, атрибуты Spread JSX эквивалентны Распаковать списки аргументов (Python ** -оператор).

Я знаю, что это вопрос JSX, но работа с аналогами иногда помогает ускорить его работу.

8

... (оператор распространения) используется в реакции на:

обеспечить удобный способ передачи реквизита от родительских компонентов к дочерним. например, учитывая эти реквизиты в родительском компоненте,

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

они могут быть переданы следующим образом ребенку,

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

что похоже на это

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

но способ чище.

3

Три точки (...) называются оператором спрединга, и это концептуально похоже на оператор распределения массивов ES6, JSX используя эти поддерживаемые и разрабатываемые стандарты, чтобы обеспечить более чистый синтаксис в JSX

Свойства спреда в инициализаторах объектов копируют собственные перечислимые свойства из предоставленного объекта на вновь созданный объект.

let n = { x, y, ...z };
n; // { x: 1, y: 2, a: 3, b: 4 }

Ссылка:

1) https://github.com/sebmarkbage/ecmascript-rest-spread#spread-properties

2) https://facebook.github.io/react/docs/jsx-spread.html

  • 3
    Это предложение для оператора распространения на объектах в ECMAScript. Вопрос был об операторе распространения JSX. Они не одинаковы, хотя они работают одинаково.
  • 1
    @ivarni Спасибо за то, что вывели меня в контекст, дайте мне минутку, обновите ответ в зависимости от контекста вопроса.
Показать ещё 1 комментарий
2

Короче говоря, три точки... это оператор распространения в ES6 (ES2015). оператор распространения будет получать все данные.

let a = [1, 2, 3, 4];
let b = [...a, 4, 5, 6];
let c = [7,8,...a];

console.log (б); дать результат [1,2,3,4,5,6]

console.log (с); дать результат [7,8,1,2,3,4]

1

Обычно называется оператором распространения, он используется для расширения везде, где требуется

пример

const SomeStyle = {
   margin:10,
   background:#somehexa
}

вы можете использовать это там, где вам когда-либо потребуется, больше об операторе распространения https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

0

Обычная практика - передавать информацию в приложении React. При этом мы можем применить изменения состояния к дочернему компоненту независимо от того, является он чистым или нечистым (без сохранения состояния или с сохранением состояния). Бывают моменты, когда наилучшим подходом при переходе в реквизит является передача отдельных свойств или целого объекта свойств. С поддержкой массивов в 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-распространение или 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';

Или объедините два разных объекта, как это (это еще не доступно во всех версиях реакции):

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

Другой способ объяснить это, согласно сайту реакции/документации Facebook:

Если у вас уже есть "props" в качестве объекта и вы хотите передать его в JSX, вы можете использовать "..." как оператор SPREAD для передачи всего объекта "props". Следующие два примера эквивалентны:

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



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

Атрибуты распространения могут быть полезны при создании универсальных контейнеров. Тем не менее, они также могут сделать ваш код беспорядочным, упрощая передачу ненужных реквизитов компонентам, которые не заботятся о них. Этот синтаксис следует использовать с осторожностью.

0

Это называется синтаксис спредов в javascript.

Он используется для деструктурирования массива или объекта в JavaScript.

пример:

const objA = { a: 1, b: 2, c: 3 }
const objB = { ...objA, d: 1 }
/* result of objB will be { a: 1, b: 2, c: 3, d: 1 } */
console.log(objB)

const objC = { ....objA, a: 3 }
/* result of objC will be { a: 3, b: 2, c: 3, d: 1 } */
console.log(objC)

Вы можете сделать то же самое с Object.assign() функции Object.assign() в javascript.

Ссылка:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

0

Атрибуты Spread, используемые для простой передачи нескольких свойств

{... this.props} содержит свойство this.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 } />

Твиттер Дана Абрамова об операторе распространения (создатель Redux) https://twitter.com/dan_abramov/status/694519379191545856?lang=en

-1

В вашем конкретном примере оператор с расширением передаст все внутри объекта реквизита.

Я нашел этот веб-сайт действительно полезным при запуске с реакцией: https://zhenyong.github.io/react/docs/jsx-spread.html

-2

Это новая функция в ES6/Harmony. Он называется Оператором распространения. Он позволяет либо отделить составные части массива/объекта, либо взять несколько элементов/параметров и склеить их вместе. Вот пример:

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

И с объектом/ключами:

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

Что действительно круто, вы можете использовать его для обозначения "остальных значений".

const myFunc = (value1, value2, ...values) {
    // Some code
}

myFunc(1, 2, 3, 4, 5)
// when myFunc is called, the rest of the variables are placed into the "values" array
-4

Они называются спредами. Как следует из названия. Это означает, что он помещает любую ценность в этот массив или объекты.

Например:

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню