删除项后,ReactJS父/子列表项无法正确呈现

时间:2016-05-20 20:57:48

标签: reactjs parent children

示例:https://jsfiddle.net/wbellman/ghuw2ers/6/

在我正在处理的应用程序中,我有一个父容器(在我的示例中为List),其中包含一个子列表(在我的示例中为Hero)。该列表由外部对象控制。为简单起见,我直接在JS中声明了对象。 (在我的实际应用程序中,数据存储正确地命名空间等等。)

我遇到的问题是在列表中我有三个元素,如果我从中间删除一个项目,渲染列表似乎删除了最后一个元素。但是外部对象反映了正确的列表。

例如:

  • 我的清单中有元素:cap,thor,hulk
  • 如果你删除" thor"," cap"和" thor"呈现
  • heroList反映" cap"和" hulk"应该

我对ReactJs相对较新,所以我的前提很有可能从根本上存在缺陷。

注意:该示例反映了一个更复杂的应用程序。它的结构类似于演示目的。我知道你可以制作一个单独的组件,但它在实际的应用程序中是不实际的。

任何帮助都将不胜感激。

以下是来自JSFiddle的代码:

  var heroList = [
    { name: "cap" },
     { name: "thor"},
    { name: "hulk"}
  ];

  var List = React.createClass({
    getInitialState() {
      console.log("heros", heroList);
      return {
        heros: heroList
      };
    },

    onChange(e){
      this.setState({heros: heroList});
    },

    removeHero(i,heros){
      var hero = heros[i];
      console.log("removing hero...", hero);
       heroList = _.filter(heroList, function(h){ return h.name !== hero.name;});
      this.setState({heros:heroList});
    },

    render() {
      var heros = this.state.heros;

      var createHero = (hero,index) => {
        return <Hero hero={hero} key={index} onRemove={this.removeHero.bind(this,index,heros)}/>;
      };


      console.log("list", heros);

      return (  
        <ul>
          {heros.map(createHero)}
        </ul>
       )
    }
  });

  var Hero = React.createClass({

    getInitialState() {
      return {
        hero: this.props.hero
      }
    },

    render() {
      var hero = this.state.hero;
      return (
        <li>Hello {hero.name} | <button type="button" onClick={this.props.onRemove}>-</button></li>
      );
    }
  });

  ReactDOM.render(
    <List />,
    document.getElementById('container')
  );

附加:我在从JSFiddle复制代码时遇到问题,我意外破解的任何内容都应该在这个问题顶部列出的JSFiddle中工作。

修改

基于madox2nicolenuwayDamien Leroux的评论,这里是我最终做的事情:

https://jsfiddle.net/wbellman/ghuw2ers/10/

我希望有一种方法可以给予每个人信任,你们都是一个很大的帮助。

3 个答案:

答案 0 :(得分:2)

将Hero课程改为此修复了为我显示错误的英雄名称的问题:

var Hero = React.createClass({
  render() {
    return (
      <li>Hello {this.props.hero.name} | <button type="button" onClick={this.props.onRemove}>-</button></li>
    );
  }
});

即。我从班级中删除了本地州并直接使用道具。

一般来说,只有在真正需要时才尝试使用本地商店。试着将你的组件视为无状态,即他们通过道具得到一些东西并显示它,就是这样。

沿着这些方向,你应该考虑通过道具将英雄列表传递给你的List组件。

答案 1 :(得分:0)

如果您在管理数据时确实遇到问题,则应使用Flux或Redux。

在此代码中:

heroList = _.filter(heroList, function(h){ return h.name !== hero.name;});

我只是不明白为什么你提交heroList而不是this.state.heros?每次添加或删除英雄时,当前范围内的heroList都不应保持状态?全局heroList只是初始状态。

答案 2 :(得分:-2)

问题在于使用了密钥。由于密钥是从索引中获取的,因此该密钥已被使用,因此显示了具有该密钥的英雄。

将其更改为key={Math.random() * 100}并且可以正常使用