所以,我一直在使用我的第一个ReactJS
应用。只需一个简单的表单,您可以在其中键入电影名称,然后从IMDB
获取数据并将其作为模块添加到页面上。这一切都正常。
但是每个电影模块也有一个删除按钮,该按钮应该删除该特定模块并触发重新渲染。这不是很好,因为无论您点击哪个按钮,它都会删除最后添加的电影模块而不是您点击的那个模块。
应用: http://lukeharrison.net/react/
Github代码库: https://github.com/WebDevLuke/React-Movies
我只是想知道是否有人可以发现这背后的原因?
干杯!
答案 0 :(得分:0)
我不确定为什么它没有正确呈现,因为数据集看起来很好。
查看代码,我会将删除功能更改为此...
var index = this.state.movies.indexOf(movieToRemove);
console.log(this.state.movies);
if (index > -1) {
this.state.movies.splice(index, 1);
}
console.log(this.state.movies);
this.setState(this.state.movies);
我的假设是,状态未正确更新。每当更新状态时,你应该总是使用setState(除非约定改变了,我不知道)。
此外,您不需要显式调用forceUpdate。一旦调用了setState,React将自动执行它所需的操作并使用新状态重新渲染。
答案 1 :(得分:0)
只是预感,但您应该使用唯一的key
,而不仅仅是地图功能的索引。这样React就会明白电影不是通过一些迭代索引来识别的,而是一个实际值,这可能会解决你的问题。
var movies = this.state.movies.map(function(movie, index){
return (
<Movie key={movie} useKey={index} removeMovieFunction={component.removeMovie} search={movie} toggleError={component.toggleError} />
);
});
这是因为React重新评估您的属性,发现没有任何更改,只是从列表中删除了最后一个<Movie />
。每部电影的componentDidMount
功能永远不会运行一次,电影1,电影2和电影3的状态仍然存在。因此,即使您提供search={movie}
,它也无法执行任何操作,因为this.props.search
仅用于componentDidMount
。
答案 2 :(得分:0)
状态应该是从顶级组件(称为容器)单向(从顶部向下传递)。在这种情况下,您在顶级组件中有搜索字符串的状态,然后通过IMDB API从“Movie”组件本身加载单个电影数据。
您应该重构代码以处理顶级容器中的所有状态,并仅将完整的影片数据传递给哑“Movie”组件。所有它应该关心的是渲染你传递它的道具而不是获取它自己的数据。