草庐IT

javascript - 在 React.js 中将 key 传递给 child

coder 2024-05-09 原文

我正在浏览一个关于 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 函数中的键,但是键 Prop 没有被正确传递。所以我的问题是,我如何通过这种“单向流”将它们传递给我的父组件?

注意:请随意指出其他问题或更好的设计决策,或绝对的愚蠢。甚至我问错了问题。

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

最佳答案

The key prop has a special meaning in React .它不会作为 prop 传递给组件,但会被 React 用来帮助协调集合。如果你知道d3 ,它的工作原理类似于 selection.data() 的关键功能。它允许 React 将前一棵树的元素与下一棵树的元素相关联。

你有一个 key 很好(如果你传递一个元素数组,你需要一个),但是如果你想把这个值传递给组件,你应该有另一个属性:

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

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

关于javascript - 在 React.js 中将 key 传递给 child ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30465651/

有关javascript - 在 React.js 中将 key 传递给 child的更多相关文章

  1. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  2. ruby - rails 3 redirect_to 将参数传递给命名路由 - 2

    我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use

  3. ruby-on-rails - 如何生成传递一些自定义参数的 `link_to` URL? - 2

    我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些

  4. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  5. ruby-on-rails - Ruby - 如何从 ruby​​ 上的 .pfx 文件中提取公钥、rsa 私钥和 CA key - 2

    我有一个.pfx格式的证书,我需要使用ruby​​提取公共(public)、私有(private)和CA证书。使用shell我可以这样做:#ExtractPublicKey(askforpassword)opensslpkcs12-infile.pfx-outfile_public.pem-clcerts-nokeys#ExtractCertificateAuthorityKey(askforpassword)opensslpkcs12-infile.pfx-outfile_ca.pem-cacerts-nokeys#ExtractPrivateKey(askforpassword)o

  6. ruby - 在 Ruby 中将整数格式化为固定长度的字符串 - 2

    有没有一种简单的方法可以将给定的整数格式化为具有固定长度和前导零的字符串?#convertnumberstostringsoffixedlength3[1,12,123,1234].map{|e|???}=>["001","012","123","234"]我找到了解决方案,但也许还有更聪明的方法。format('%03d',e)[-3..-1] 最佳答案 如何使用%1000而不是进行字符串操作来获取最后三位数字?[1,12,123,1234].map{|e|format('%03d',e%1000)}更新:根据theTinMan的

  7. ruby - 如何将 Puma::Configuration 传递给 Sinatra? - 2

    这是我的网络应用:classFront我是这样开始的(请不要建议使用Rack):Front.start!这是我的Puma配置对象,我不知道如何传递给它:require'puma/configuration'Puma::Configuration.new({log_requests:true,debug:true})说真的,怎么样? 最佳答案 配置与您运行的方式紧密相关puma服务器。运行的标准方式puma-pumaCLI命令。为了配置puma配置文件config/puma.rb或config/puma/.rb应该提供(参见examp

  8. ruby - 无法在 Ruby 中将 ffmpeg 作为子进程运行 - 2

    我正在尝试使用以下代码通过将ffmpeg实用程序作为子进程运行并获取其输出并解析它来确定视频分辨率:IO.popen'ffmpeg-i'+path_to_filedo|ffmpegIO|#myparsegoeshereend...但是ffmpeg输出仍然连接到标准输出并且ffmepgIO.readlines是空的。ffmpeg实用程序是否需要一些特殊处理?或者还有其他方法可以获得ffmpeg输出吗?我在WinXP和FedoraLinux下测试了这段代码-结果是一样的。 最佳答案 要跟进mouviciel的评论,您需要使用类似pope

  9. jquery - 如何将 AJAX 变量从 jQuery 传递到他们的 Controller ? - 2

    我有一个电子邮件表格。但是我正在制作一个测试电子邮件表单,用户可以在其中添加一个唯一的电子邮件,并让电子邮件测试将其发送到该特定电子邮件。为了简单起见,我决定让测试电子邮件通过ajax执行,并将整个内容粘贴到另一个电子邮件表单中。我不知道如何将变量从我的HAML发送到我的Controllernew.html.haml-form_tagadmin_email_blast_pathdoSubject%br=text_field_tag'subject',:class=>"mass_email_subject"%brBody%br=text_area_tag'message','',:nam

  10. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

随机推荐