React.propTypes
ОБНОВЛЕНИЕ 2018: в учебнике хорошая теория, но ему уже два года. Проверяйте версии пакетов. За выходом нового учебника можно следить в telegram канале или twitter
На канале так же проводятся бесплатные вебинары, публикуются переводы и авторские материалы, присоединяйтесь!
React.propTypes
(скучный, но небольшой теоретический перекур)
Перед выполнением данного урока, не забывайте, что PropTypes не работает с production версией реакта. Эта фича только для разработки, так как валидация - дорогая операция.
Давайте сломаем наш код:
var App = React.createClass({
render: function() {
return (
<div className='app'>
<h3>Новости</h3>
<News /> {/* удалили data = {my_news} */}
</div>
);
}
});
Обновим страницу - видим сообщение об ошибке.
В принципе, все понятно - мы пытаемся вызвать метод map у undefined. У примитива undefined, как известно никаких методов нет - ошибка, получите распишитесь. Хорошо, что кода мало и мы быстро выяснили в чем проблема. Еще лучше, что есть возможность улучшить наше положение, добавив propTypes - специальное свойство, которое будет "валидировать" наш компонент.
Внесите изменения в компонент <News />
var News = React.createClass({
propTypes: {
data: React.PropTypes.array.isRequired
},
render: function() {
var data = this.props.data;
var newsTemplate;
if (data.length > 0) {
newsTemplate = data.map(function(item, index) {
return (
<div key={index}>
<Article data={item} />
</div>
)
})
} else {
newsTemplate = <p>К сожалению новостей нет</p>
}
return (
<div className='news'>
{newsTemplate}
<strong className={'news__count ' + (data.length > 0 ? '':'none') }>Всего новостей: {data.length}</strong>
</div>
);
}
});
Обновите страницу:
Гораздо лучше! Исходя из текста ошибки нам сразу понятно куда копать: в render методе App, не указано свойство data, которое ожидается в News. Восстановим свойство data.
var App = React.createClass({
render: function() {
return (
<div className='app'>
<h3>Новости</h3>
<News data={my_news}/>
</div>
);
}
});
Вновь все работает, и наша консоль чиста.
Подробнее о propTypes
Приведу выдержку из офф.документации:
React.createClass({
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,
// Вы может указать, что свойство можеть быть одни из ...
optionalUnion: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.number,
React.PropTypes.instanceOf(Message)
]),
// Вы можете указать, конкретную структуру объекта свойства
optionalObjectWithShape: React.PropTypes.shape({
color: React.PropTypes.string,
fontSize: React.PropTypes.number
}),
// Вы можете указать, что свойство ОБЯЗАТЕЛЬНО
requiredFunc: React.PropTypes.func.isRequired,
// Если нужно указать, что свойство просто обязательно, и может быть любым примитивом
requiredAny: React.PropTypes.any.isRequired,
}
});
Согласно этому листингу, мы можем перевести правило, указанное в компоненте <News />
:
React.PropTypes.array.isRequired
- свойство должно быть массивом и оно обязательно должно быть!
Я вижу по глазам некоторых (да-да, вижу), что все это какая-то бесполезная лабуда. Итак понятно - есть ошибка, есть возможность тыкнуть на нее в дебаггере и посмотреть. Специально для вас, следующая ситуация: удалите из массива my_news автора, например в третьем элементе:
var my_news = [
{
author: 'Саша Печкин',
text: 'В четчерг, четвертого числа...'
},
{
author: 'Просто Вася',
text: 'Считаю, что $ должен стоить 35 рублей!'
},
{
text: 'Бесплатно. Скачать. Лучший сайт - http://localhost:3000'
}
];
Посмотрим результат:

Никаких ошибок. Но наше приложение не работает так как надо. Кто виноват? Реакт? Backend-программист который прислал нам такие данные?
Программист, может и виноват. Но реакт точно нет. У нас получилось, что в this.props.data.author
содержится undefined
(переменнная не определена). Поэтому react так и поступил, и показал нам "ничего" (на скриншоте это только "двоеточие").

Такую ошибку сложно отловить.
Добавьте propTypes в компонент <Article />
var Article = React.createClass({
propTypes: {
data: React.PropTypes.shape({
author: React.PropTypes.string.isRequired,
text: React.PropTypes.string.isRequired
})
},
render: function() {
var author = this.props.data.author,
text = this.props.data.text;
return (
<div className='article'>
<p className='news__author'>{author}:</p>
<p className='news__text'>{text}</p>
</div>
)
}
});
В таком случае вы получите сообщение об ошибке:

Разве это не прекрасно?
Исходный код на данный момент.
P.S. Не забудьте вернуть автора ;)
Last updated
Was this helpful?