我正在运行有关tutsplus的React教程,该教程有点旧,并且该代码无法正常工作。实际上,我对此完全满意,因为它迫使我独立学习,但是我花了一段时间解决了一个我无法弄清的错误。该错误包括无法传递对象键,这阻止了我的程序更新正确对象的状态。
如果要运行此代码并在运行中查看它,那么这里首先是存储库: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> ); } });
哪个应该在父组件的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函数中的键,但是键属性未正确传递。所以我的问题是,如何通过“单向流程”将它们的密钥传递给父组件?
注意:请随时指出其他问题或更好的设计决策或绝对的愚蠢。甚至那个我在问一个错误的问题。
期待对这个很酷的框架进行很好的探索。
该key道具在React中有特殊含义。它不会作为prop传递给组件,而是被React用于帮助协调集合。如果您知道d3,它的作用类似于的键功能selection.data()。它允许React将前一棵树的元素与下一棵树的元素关联。
key
selection.data()
最好有一个key(如果传递一个元素数组,则需要一个),但是如果要将该值传递给组件,则应该使用另一个道具:
<FeedItem key={item.key} id={item.key} ... />
(并访问this.props.id组件内部)。
this.props.id