在React.js中将密钥传递给子代 [英] Passing keys to children in React.js

查看:34
本文介绍了在React.js中将密钥传递给子代的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在运行有关tutsplus的React教程,该教程有点旧,并且该代码无法正常工作.实际上,我对此完全满意,因为它迫使我独立学习,但是我花了一段时间解决了一个我无法弄清的错误.该错误包括无法传递对象键,这阻止了我的程序更新正确对象的状态.

I am running through a react tutorial on tutsplus that is a bit old, and the code doesn't work as it was originally written. I actually am totally ok with this as it forces me to learn more independently, however I have spent a while on a bug that I just can't figure out. The bug consists of not being able to pass on an objects key, which prevents my program from updating the state of the correct object.

如果要运行此代码并在运行中查看它,那么这里首先是存储库: https://github.com/camerow/react-voteit

First off here is the repo if you want to run this code and see it in action: https://github.com/camerow/react-voteit

我有一个看起来像这样的子组件:

I have a child component that looks like this:

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组件:

Now when someone hits the vote button the desired behavior is for the FeedItem.vote() method to send an object up to the main Feed component:

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函数传递该键:

Which should pass that key on throught the parent component's onVote function:

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函数中的键,但是键属性未正确传递.所以我的问题是,如何通过单向流"将它们的密钥传递给父组件?

My logic relies on being able to reconcile the keys in the onVote function, however the key prop is not being properly passed on. So my question is, how do I pass on they key through this 'one way flow' to my parent component?

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

Note: Feel free to point out other problems or better design decision, or absolute stupidities. Or even that I'm asking the wrong question.

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

Looking forward to a nice exploration of this cool framework.

推荐答案

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

The key prop has a special meaning in React. It it is not passed to the component as prop but is used by React to aid the reconciliation of collections. If you know d3, it works similar like the key function for selection.data(). It allows React to associate the elements of the previous tree with the elements of the next tree.

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

It's good that you have a key (and you need one if you pass an array of elements), but if you want to pass that value along to the component, you should another prop:

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

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

(and access this.props.id inside the component).

这篇关于在React.js中将密钥传递给子代的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆