示例:https://jsfiddle.net/wbellman/ghuw2ers/6/
在我正在处理的应用程序中,我有一个父容器(在我的示例中为List),其中包含一个子列表(在我的示例中为Hero)。该列表由外部对象控制。为简单起见,我直接在JS中声明了对象。 (在我的实际应用程序中,数据存储正确地命名空间等等。)
我遇到的问题是在列表中我有三个元素,如果我从中间删除一个项目,渲染列表似乎删除了最后一个元素。但是外部对象反映了正确的列表。
例如:
我对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中工作。
修改
基于madox2,nicole,nuway和Damien Leroux的评论,这里是我最终做的事情:
https://jsfiddle.net/wbellman/ghuw2ers/10/
我希望有一种方法可以给予每个人信任,你们都是一个很大的帮助。
答案 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}
并且可以正常使用