【发布时间】:2016-12-29 04:27:33
【问题描述】:
我正在开发简单的流应用程序。我有帖子列表,这个列表可以接收更新,它会显示在上面。
问题是在每个新帖子上接收 React 都会重新呈现整个元素列表。我已经为它做了一个简单的例子。
有没有办法避免这种行为? 我在 React 文档上看到了 dynamic-children 主题,但例如,正如你所见,我已经更新了所有的孩子。
class Post extends React.Component {
render() {
console.log('rerendered post', this.props.reactKey);
return (
<li>{this.props.post.text}</li>
);
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {posts: [
{id: '00001', text: 'First one'},
{id: '00002',text: 'Second one'},
{id: '00003',text: 'Third one'}
]};
}
addPost() {
const posts = this.state.posts;
posts.unshift({id: '00004', text: 'New post'});
this.setState({posts: posts});
}
render() {
return (
<div>
<button onClick={this.addPost.bind(this)}>Add Post</button>
<ul>
{this.state.posts.map((post, index) => {
return (<Post post={post} key={post.id} reactKey={index} />);
})}
</ul>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<body>
<div id="root"></div>
</body>
解决方案
问题是我使用 .map 函数的索引是每个列表组件的键而不是唯一键。而且因为在添加新元素以列出所有索引后更改为+1,所以第一个帖子变成了第二个,我所有的帖子都重新渲染了。 所以首先,检查你在所有列表元素中使用唯一键:-)
【问题讨论】:
-
多次调用 render 并没有错,React 只会更新 DOM 的实际变化。在每个组件上调用 render 以确定是否有任何变化。如果您确定在您的组件中它甚至应该尝试调用渲染(我重申这很好),您可以使用
shouldComponentUpdate -
问题是我不需要重新渲染旧帖子,因为有一些 API 调用等功能。我希望它们保持原样,只添加和渲染新帖子.
-
那你必须使用
shouldComponentUpdate来判断是否有相关的props发生了变化
标签: javascript dom reactjs