Я прохожу через учебник по реагированию на tutsplus, который немного стар, и код не работает, поскольку он был изначально написан. Я на самом деле полностью в порядке с этим, поскольку он заставляет меня учиться более самостоятельно, однако я потратил некоторое время на ошибку, которую я просто не могу понять. Ошибка состоит в том, что вы не можете передать ключ объектов, что предотвращает обновление моей программы из состояния правильного объекта.Передача ключей детям в React.js
Во-первых здесь репо, если вы хотите запустить этот код и увидеть его в действии: https://github.com/camerow/react-voteit
У меня есть компонент ребенка, который выглядит следующим образом:
var FeedItem = React.createClass({
vote: function(newCount) {
console.log("Voting on: ", this.props, " which should have a key associated.");
this.props.onVote({
key: this.props.key,
title: this.props.title,
description: this.props.desc,
voteCount: newCount
});
},
voteUp: function() {
var count = parseInt(this.props.voteCount, 10);
var newCount = count + 1;
this.vote(newCount);
},
voteDown: function() {
var count = parseInt(this.props.voteCount, 10);
var newCount = count - 1;
this.vote(newCount);
},
render: function() {
var positiveNegativeClassName = this.props.voteCount >= 0 ?
'badge badge-success' :
'badge badge-danger';
return (
<li key={this.props.key} className="list-group-item">
<span className={positiveNegativeClassName}>{this.props.voteCount}</span>
<h4>{this.props.title}</h4>
<span>{this.props.desc}</span>
<span className="pull-right">
<button id="up" className="btn btn-sm btn-primary" onClick={this.voteUp}>↑</button>
<button id="down" className="btn btn-sm btn-primary" onClick={this.voteDown}>↓</button>
</span>
</li>
);
}
});
Теперь, когда кто-то ударяет кнопка вотума желаемого поведения для метода FeedItem.vote() для отправки объекта до основного компонента Feed:
var FeedList = React.createClass({
render: function() {
var feedItems = this.props.items;
return (
<div className="container">
<ul className="list-group">
{feedItems.map(function(item) {
return <FeedItem key={item.key}
title={item.title}
desc={item.description}
voteCount={item.voteCount}
onVote={this.props.onVote} />
}.bind(this))}
</ul>
</div>
);
}
});
, который должен пройти этот ключ на Thr должно onVote функция родительского компонента:
var Feed = React.createClass({
getInitialState: function() {
var FEED_ITEMS = [
{
key: 1,
title: 'JavaScript is fun',
description: 'Lexical scoping FTW',
voteCount: 34
}, {
key: 2,
title: 'Realtime data!',
description: 'Firebase is cool',
voteCount: 49
}, {
key: 3,
title: 'Coffee makes you awake',
description: 'Drink responsibly',
voteCount: 15
}
];
return {
items: FEED_ITEMS,
formDisplayed: false
}
},
onToggleForm: function() {
this.setState({
formDisplayed: !this.state.formDisplayed
});
},
onNewItem: function (newItem) {
var newItems = this.state.items.concat([newItem]);
// console.log("Creating these items: ", newItems);
this.setState({
items: newItems,
formDisplayed: false,
key: this.state.items.length
});
},
onVote: function (newItem) {
// console.log(item);
var items = _.uniq(this.state.items);
var index = _.findIndex(items, function (feedItems) {
// Not getting the correct index.
console.log("Does ", feedItems.key, " === ", newItem.key, "?");
return feedItems.key === newItem.key;
});
var oldObj = items[index];
var newItems = _.pull(items, oldObj);
var newItems = this.state.items.concat([newItem]);
// newItems.push(item);
this.setState({
items: newItems
});
},
render: function() {
return (
<div>
<div className="container">
<ShowAddButton displayed={this.state.formDisplayed} onToggleForm={this.onToggleForm}/>
</div>
<FeedForm displayed={this.state.formDisplayed} onNewItem={this.onNewItem}/>
<br />
<br />
<FeedList items={this.state.items} onVote={this.onVote}/>
</div>
);
}
});
Моя логика опирается на возможность согласовать ключи в onVote функции, однако ключ проп не должным образом передается. Итак, мой вопрос: как я могу пройти через этот «один путь потока» к моему родительскому компоненту?
Примечание: Не стесняйтесь указывать на другие проблемы или лучшее дизайнерское решение или абсолютные глупости. Или даже я задаю неправильный вопрос.
С нетерпением ждем прекрасного изучения этой прохладной рамки.
'ключ' имеет специальное значение в Реагировании. Он не доступен для компонента через 'this.props.key' afaik. Для этого вы должны использовать другое имя. Или, если вы действительно хотите использовать значение как ключ, добавьте дополнительную опору с тем же самым, что вы можете затем получить доступ к компоненту. См. Https://facebook.github.io/react/docs/multiple-components.html#dynamic-children –
Ах, хорошо, это очень помогло. Я уже прочитал эту документацию, но был немного озадачен ею. Поэтому, чтобы уточнить, для меня нормально определять prop 'key', но он должен выглядеть как' '? Или я должен избегать «ключа» вообще? –
camerow
По-прежнему получать это предупреждение 'Предупреждение: каждый ребенок в массиве или итераторе должен иметь уникальную« ключевую »опору. Проверьте метод рендеринга FeedList. См. Https://fb.me/react-warning-keys для получения дополнительной информации. ', Хотя изменение всех экземпляров' key' на 'id' позволило мне передать эту подсказку. – camerow