因此,据我所知,反应只会用新密钥重新渲染新元素。这不适合我。 我有一个帖子列表,限于3个。 当用户滚动到页面底部时,我添加3到限制,这意味着在页面的底部3应该显示较旧的帖子。 我现在所做的工作,但整个清单正在被重新渲染。它跳到顶部,这也是不想要的(我可以修复,主要问题是重新渲染)。他们都有独特的钥匙。我该如何防止这种行为?
thisGetsCalledWhenANewPostComesIn(newPost){
let newPosts = _.clone(this.state.posts);
newPosts.push(newPost);
newPosts.sort((a,b) => b.time_posted - a.time_posted);
this.setState({posts: newPosts});
}
render(){
return (
<div ref={ref => {this.timelineRef = ref;}} style={styles.container}>
{this.state.posts.map(post =>
<Post key={post.id} post={post} />
)}
</div>
);
}
答案 0 :(得分:3)
单独使用唯一键不会阻止重新渲染未更改的组件。除非您为组件扩展PureComponent或实施shouldComponentUpdate,否则React必须render()
组件并将其与上一个结果进行比较。
shouldComponentUpdate
?为列表中的每个组件提供唯一键的目的是将道具传递给&#34;右键#34;组件实例,以便他们可以正确地比较新旧道具。
想象一下,我们有一个项目列表,例如:
应用过滤器后,必须重新呈现列表以显示新的组件列表,例如:
如果没有正确的唯一键,之前呈现A
的组件现在将收到C
的道具。即使C
未更改,组件也必须在收到完全不同的数据时重新呈现:
使用正确的唯一键,呈现C
的组件将再次收到C
。然后shouldComponentUpdate
将能够认识到render()输出是相同的,并且组件不必重新渲染:
如果您的商品列表需要很长时间才能呈现,例如如果它是一个长列表或每个元素都是一组复杂的数据,那么您将从防止不必要的重新渲染中受益。
在一个包含100个项目列表的项目中,每个项目生成1000个DOM元素,从
更改list.map((item, index) => <SomeComp key={index} ... />)
到
list.map(item => <SomeComp key={item.id} ... />)
将渲染时间缩短了几秒钟。切勿使用数组索引作为键。
答案 1 :(得分:0)
您必须在Post
组件中实施shouldComponentUpdate(nextProps, nextState)。考虑扩展Post
组件的PureComponent类,而不是默认的React Component
。
PS:您可以在渲染方法中使用字符串作为div的ref参数,如下所示:
render() {
return (
<div
ref='myRef'
style={styles.container}
>
{this.getPostViews()}
</div>
);
}
然后,如果您想引用此元素,请像this.refs.myRef
一样使用它。无论如何,这只是个人偏好。
答案 2 :(得分:0)
好的,我的坏。我以为我只发布相关的&#34;代码,但事实证明,问题出在我遗漏的代码中:
this.setState({posts: []}, ()=> {
this.postListenerRef = completedPostsRef.orderByChild('time')
.startAt(newProps.filter.fromDate.getTime())
.endAt(newProps.filter.toDate.getTime())
.limitToLast(this.props.filter.postCount)
.on('child_added', snap => {
Database.fetchPostFromKey(snap.key)
.then(post => {
let newPosts = _.clone(this.state.posts);
newPosts.push(_.assign(post, {id: snap.key}));
newPosts.sort((a,b) => b.time_posted - a.time_posted);
this.setState({posts: newPosts});
}).catch(err => {throw err;});
});
});
我致电setState({posts: []})
,我肯定是99%。