React
Реквизит в действии
Поиск…
замечания
ПРИМЕЧАНИЕ. Что касается React 15.5, и компонент PropTypes живет в своем собственном пакете npm, а именно: «prop-types» и ему нужен собственный оператор импорта при использовании PropTypes. См. Официальную документацию о реакции на изменение: https://facebook.github.io/react/blog/2017/04/07/react-v15.5.0.html
Вступление
props
используются для передачи данных и методов из родительского компонента в дочерний компонент.
Интересные вещи о props
- Они неизменны.
- Они позволяют нам создавать повторно используемые компоненты.
Основной пример
class Parent extends React.Component{
doSomething(){
console.log("Parent component");
}
render() {
return <div>
<Child
text="This is the child number 1"
title="Title 1"
onClick={this.doSomething} />
<Child
text="This is the child number 2"
title="Title 2"
onClick={this.doSomething} />
</div>
}
}
class Child extends React.Component{
render() {
return <div>
<h1>{this.props.title}</h1>
<h2>{this.props.text}</h2>
</div>
}
}
Как вы можете видеть в этом примере, благодаря props
мы можем создавать повторно используемые компоненты.
Репозитории по умолчанию
defaultProps
позволяет установить по умолчанию, или запасной вариант, значения для компонента props
. defaultProps
полезны, когда вы вызываете компоненты из разных представлений с фиксированными реквизитами, но в некоторых представлениях вам нужно передать другое значение.
Синтаксис
ES5
var MyClass = React.createClass({
getDefaultProps: function() {
return {
randomObject: {},
...
};
}
}
ES6
class MyClass extends React.Component {...}
MyClass.defaultProps = {
randomObject: {},
...
}
ES7
class MyClass extends React.Component {
static defaultProps = {
randomObject: {},
...
};
}
Результат getDefaultProps()
или defaultProps
будет кэшироваться и использоваться для обеспечения того, что this.props.randomObject
будет иметь значение, если он не был указан родительским компонентом.
PropTypes
propTypes
позволяет указать, какие props
нужны вашему компоненту и какой тип они должны быть. Ваш компонент будет работать без установки propTypes
, но это хорошая практика, чтобы определить их, поскольку это сделает ваш компонент более читабельным, станет документом для других разработчиков, которые читают ваш компонент, а во время разработки React предупредит вас, если вы попытаетесь установите опору, которая отличается от определения, которое вы установили для него.
Некоторые примитивные propTypes
и обычно используемые propTypes
-
optionalArray: React.PropTypes.array,
optionalBool: React.PropTypes.bool,
optionalFunc: React.PropTypes.func,
optionalNumber: React.PropTypes.number,
optionalObject: React.PropTypes.object,
optionalString: React.PropTypes.string,
optionalSymbol: React.PropTypes.symbol
Если вы прикрепляете isRequired
к любому propType
тогда эта поддержка должна быть предоставлена при создании экземпляра этого компонента. Если вы не предоставите требуемые propTypes
то экземпляр компонента не может быть создан.
Синтаксис
ES5
var MyClass = React.createClass({
propTypes: {
randomObject: React.PropTypes.object,
callback: React.PropTypes.func.isRequired,
...
}
}
ES6
class MyClass extends React.Component {...}
MyClass.propTypes = {
randomObject: React.PropTypes.object,
callback: React.PropTypes.func.isRequired,
...
};
ES7
class MyClass extends React.Component {
static propTypes = {
randomObject: React.PropTypes.object,
callback: React.PropTypes.func.isRequired,
...
};
}
Более сложная проверка реквизита
Точно так же PropTypes
позволяет указать более сложную проверку
Проверка объекта
...
randomObject: React.PropTypes.shape({
id: React.PropTypes.number.isRequired,
text: React.PropTypes.string,
}).isRequired,
...
Проверка массива объектов
...
arrayOfObjects: React.PropTypes.arrayOf(React.PropTypes.shape({
id: React.PropTypes.number.isRequired,
text: React.PropTypes.string,
})).isRequired,
...
Передача реквизита с помощью оператора спредов
Вместо
var component = <Component foo={this.props.x} bar={this.props.y} />;
Если каждое свойство должно быть передано в качестве единственного значения поддержки, вы можете использовать оператор спреда ...
поддерживаемый для массивов в ES6 для передачи всех ваших значений. Теперь компонент будет выглядеть следующим образом.
var component = <Component {...props} />;
Помните, что свойства объекта, который вы передаете, копируются на реквизиты компонента.
Порядок важен. Более поздние атрибуты переопределяют предыдущие.
var props = { foo: 'default' };
var component = <Component {...props} foo={'override'} />;
console.log(component.props.foo); // 'override'
Другим случаем является то, что вы также можете использовать оператор спреда для передачи только частей реквизита для дочерних компонентов, тогда вы можете снова использовать синтаксис деструкции из реквизита.
Это очень полезно, когда компоненты для детей нуждаются в большом количестве реквизитов, но не хотят передавать их по одному.
const { foo, bar, other } = this.props // { foo: 'foo', bar: 'bar', other: 'other' };
var component = <Component {...{foo, bar}} />;
const { foo, bar } = component.props
console.log(foo, bar); // 'foo bar'
Состав реквизита и состав компонентов
« props.children
» компоненты компонента доступны на специальной опоре, props.children
. Эта пропозиция очень полезна для компонентов «Композиция» и может сделать разметку JSX более интуитивной или отражать предполагаемую окончательную структуру DOM:
var SomeComponent = function () {
return (
<article className="textBox">
<header>{this.props.heading}</header>
<div className="paragraphs">
{this.props.children}
</div>
</article>
);
}
Это позволяет нам включать произвольное количество подэлементов при использовании компонента позже:
var ParentComponent = function () {
return (
<SomeComponent heading="Amazing Article Box" >
<p className="first"> Lots of content </p>
<p> Or not </p>
</SomeComponent>
);
}
Удостоверения могут также управляться компонентом. Поскольку props.children может быть или не быть массивом , React предоставляет служебные функции для них как React.Children . Рассмотрим в предыдущем примере, если бы мы захотели обернуть каждый абзац в свой собственный элемент <section>
:
var SomeComponent = function () {
return (
<article className="textBox">
<header>{this.props.heading}</header>
<div className="paragraphs">
{React.Children.map(this.props.children, function (child) {
return (
<section className={child.props.className}>
React.cloneElement(child)
</section>
);
})}
</div>
</article>
);
}
Обратите внимание на использование React.cloneElement для удаления реквизита из дочернего <p>
поскольку реквизиты неизменяемы, эти значения не могут быть изменены напрямую. Вместо этого нужно использовать клон без этих реквизитов.
Кроме того, при добавлении элементов в циклы, знайте, как React примиряет детей во время rerender , и настоятельно рекомендуем включить глобально уникальную подсказку key
для дочерних элементов, добавленных в цикл.
Определение типа компонентов для детей
Иногда очень полезно знать тип дочернего компонента при повторении через них. Чтобы выполнить итерацию через дочерние компоненты, вы можете использовать функцию React Children.map
util:
React.Children.map(this.props.children, (child) => {
if (child.type === MyComponentType) {
...
}
});
Детский объект предоставляет свойство type
которое можно сравнить с конкретным компонентом.