Что означают эти три точки в React?
Что означает ...
в данном коде на React (с использованием JSX) и какое у него название?
<Modal {...this.props} title='Modal heading' animation={false}>
5 ответ(ов)
В данном случае ...
называется распространяемыми атрибутами (spread attributes), что, как можно понять из названия, позволяет расширять выражение.
Например, рассмотрим следующий код:
var parts = ['two', 'three'];
var numbers = ['one', ...parts, 'four', 'five']; // ["one", "two", "three", "four", "five"]
А теперь упрощенно посмотрим на следующий пример:
// Допустим, у нас есть объект:
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} />
Таким образом, мы можем сказать, что это удобный сокращенный способ записи.
Оператор расширения ...
(spread operator) используется в React для удобной передачи пропсов от родительских компонентов к дочерним. Например, если в родительском компоненте имеются следующие пропсы:
this.props = {
username: "danM",
email: "[email protected]"
}
то их можно передать в дочерний компонент следующим образом:
<ChildComponent {...this.props} />
Это эквивалентно следующему коду:
<ChildComponent username={this.props.username} email={this.props.email} />
Однако, второй вариант выглядит гораздо менее аккуратно. Использование оператора ...
позволяет сократить код и сделать его более читаемым.
В React-приложениях распространенной практикой является передача props между компонентами. Это позволяет нам применять изменения состояния к дочерним компонентам, независимо от того, являются ли они чистыми (Pure) или нечистыми (Impure), т.е. статeless или stateful. Иногда лучшим подходом к передаче props является передача отдельных свойств или целого объекта свойств. Благодаря поддержке массивов в ES6, мы получили синтаксис "..." (spread operator), который позволяет передавать целый объект дочернему компоненту.
Обычный процесс передачи props в дочерний компонент выглядит следующим образом:
var component = <Component foo={x} bar={y} />;
Этот подход может быть удобен, когда количество props минимально, но становится неуправляемым, когда их число значительно увеличивается. Проблема возникает, если вы не знаете, какие свойства нужны дочернему компоненту, и типичный способ работы с JavaScript заключается в том, чтобы просто установить эти свойства и связать их с объектом позже. Это может привести к проблемам с проверкой propTypes и запутанным ошибкам стека, которые усложняют отладку. Вот пример такого подхода и того, что не стоит делать:
var component = <Component />;
component.props.foo = x; // плохо
component.props.bar = y;
Такой же результат можно получить более подходящим способом:
var props = {};
props.foo = x;
props.bar = y;
var component = Component(props); // Где моя JSX?
Однако в этом примере не используется JSX spread, поэтому мы можем сделать так:
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';
Или объединить два разных объекта, как показано здесь (это ещё не поддерживается во всех версиях React):
var ab = { ...a, ...b }; // merge(a, b)
Еще один способ объяснения, согласно документации React от Facebook, заключается в следующем:
Если у вас уже есть props в виде объекта и вы хотите передать его в JSX, вы можете использовать "..." как оператор распределения (spread operator) для передачи всего объекта props. Следующие два примера эквивалентны:
function App1() {
return <Greeting firstName="Ben" lastName="Hector" />;
}
function App2() {
const props = {firstName: 'Ben', lastName: 'Hector'};
return <Greeting {...props} />;
}
Spread-атрибуты могут быть полезны при создании универсальных контейнеров. Тем не менее, они также могут сделать ваш код неаккуратным, так как легко передать много неуместных props в компоненты, которые не нуждаются в них. Этот синтаксис следует использовать осторожно.
Это просто другое определение props в JSX для вас!
Используется оператор ...
для массивов и объектов в ES6 (оператор для объектов пока не полностью поддерживается), так что, по сути, если вы уже определили ваши props, вы можете передать их в ваш компонент таким образом.
В вашем случае код должен выглядеть примерно так:
function yourA() {
const props = { name: 'Alireza', age: '35' };
return <Modal {...props} title='Modal heading' animation={false} />;
}
Таким образом, props, которые вы определили, теперь отделены и могут быть повторно использованы при необходимости.
Это аналогично следующему:
function yourA() {
return <Modal name='Alireza' age='35' title='Modal heading' animation={false} />;
}
Вот цитаты от команды React о операторе spread в JSX:
JSX Spread Attributes Если вы заранее знаете все свойства, которые хотите назначить компоненту, использовать JSX довольно просто:
var component = <Component foo={x} bar={y} />;
Mutating Props is Bad Если вы не знаете, какие свойства хотите установить, может возникнуть искушение добавить их в объект позже:
var component = <Component />;
component.props.foo = x; // плохо
component.props.bar = y; // тоже плохо
Это анти-шаблон, потому что означает, что мы не можем помочь вам проверить правильные
propTypes
до того, как это станет проблемой. Это приводит к тому, что ошибкиpropTypes
заканчиваются непонятным стеком вызовов.
Props следует считать неизменяемыми. Изменение объекта props где-то еще может привести к неожиданным последствиям, поэтому идеально было бы, если бы это был замороженный объект на этом этапе.
Spread Attributes Теперь вы можете использовать новую функцию JSX, называемую spread attributes:
var props = {};
props.foo = x;
props.bar = y;
var component = <Component {...props} />;
Свойства объекта, который вы передаете, копируются в props компонента.
Вы можете использовать это несколько раз или комбинировать с другими атрибутами. Порядок спецификаций важен. Поздние атрибуты переопределяют предыдущие:
var props = { foo: 'default' };
var component = <Component {...props} foo={'override'} />;
console.log(component.props.foo); // 'override'
Что за странная нотация ...? Оператор ... (или оператор spread) уже поддерживается для массивов в ES6. Существует также предложение ECMAScript для Rest и Spread Properties для объектов. Мы используем эти поддерживаемые и развивающиеся стандарты, чтобы предоставить более чистый синтаксис в JSX.
Оператор распространения (тройной оператор), введенный в ECMAScript 6 (ES6), является оберткой для JavaScript.
Оператор распространения позволяет использовать перечисляемые свойства в объектах. Рассмотрим пример с использованием свойства props
:
this.props = {
firstName: 'Dan',
lastName: 'Abramov',
city: 'New York',
country: 'USA'
}
<Modal {...this.props} title='Modal heading' animation={false} />
В приведенном выше примере {...this.props}
эквивалентно следующему объекту:
{
firstName: 'Dan',
lastName: 'Abramov',
city: 'New York',
country: 'USA'
}
Однако главная особенность оператора распространения заключается в том, что он используется для типов ссылок.
Например:
let person = {
name: 'Alex',
age: 35
}
person1 = person;
person1.name = "Raheel";
console.log(person.name); // Вывод: Raheel
Это называется типом ссылки. Один объект влияет на другие, так как они разделяют память. Если вы получаете значение независимо, это означает, что вы создали копию объекта в памяти, используя оператор распространения.
let person = {
name: 'Alex',
age: 35
}
person2 = {...person};
person2.name = "Shahzad";
console.log(person.name); // Вывод: Alex
В этом случае объект person2
является независимой копией объекта person
, и изменения в одном не влияют на другой.
Как программно выполнять навигацию с помощью React Router?
Как условно добавлять атрибуты к компонентам React?
Как установить фокус на поле ввода после рендеринга?
Метод set в useState не отражает изменения немедленно
В чем разница между React Native и React?