小编典典

在React.js中将密钥传递给子代

reactjs

我正在运行有关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}>&uarr;</button>
          <button id="down" className="btn btn-sm btn-primary" onClick={this.voteDown}>&darr;</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函数中的键,但是键属性未正确传递。所以我的问题是,如何通过“单向流程”将它们的密钥传递给父组件?

注意:请随时指出其他问题或更好的设计决策或绝对的愚蠢。甚至那个我在问一个错误的问题。

期待对这个很酷的框架进行很好的探索。


阅读 266

收藏
2020-07-22

共1个答案

小编典典

key道具在React中有特殊含义。它不会作为prop传递给组件,而是被React用于帮助协调集合。如果您知道d3,它的作用类似于的键功能selection.data()。它允许React将前一棵树的元素与下一棵树的元素关联。

最好有一个key(如果传递一个元素数组,则需要一个),但是如果要将该值传递给组件,则应该使用另一个道具:

<FeedItem key={item.key} id={item.key} ... />

(并访问this.props.id组件内部)。

2020-07-22