我正在开发简单的流应用程序。我有帖子列表,此列表可以接收更新,更新将显示在其顶部。
问题是,在每个新帖子上,React都会重新渲染整个元素列表。我为此做了一个简单的例子。
有什么办法可以避免这种行为?我已经在React docs上看到了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,因此第一条帖子成为第二条帖子,因此我的所有帖子都已重新呈现。因此,首先,请检查您是否在所有列表元素中使用唯一键:-)
只需要执行一次的工作应该在保证只能运行一次的生命周期方法中完成,例如componentDidMount
。正如文档所建议的:
如果要与其他JavaScript框架集成,请使用setTimeout或setInterval设置计时器,或发送AJAX请求,请使用此方法执行这些操作。
我componentDidMount
在您的代码段中添加了日志记录,以显示渲染发生了很多次,但是componentDidMount
每个实例仅被调用一次。
class Post extends React.Component {
componentDidMount() {
console.log('mounted post', this.props.id);
}
render() {
console.log('rerendered post', this.props.id);
return (
<li>{this.props.post.text}</li>
);
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.nextId = 4;
this.state = {
posts: [
{id: 1, text: 'First one'},
{id: 2,text: 'Second one'},
{id: 3,text: 'Third one'},
],
};
}
addPost() {
const posts = this.state.posts;
posts.unshift({id: this.nextId, text: 'Post ' + this.nextId});
this.nextId++;
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} id={post.id} />);
})}
</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>
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句