ch1*_*1p_ 37 javascript reactjs
假设我有1000个项目的列表.我用React渲染它,像这样:
class Parent extends React.Component {
render() {
// this.state.list is a list of 1000 items
return <List list={this.state.list} />;
}
}
class List extends React.Component {
render() {
// here we're looping through this.props.list and creating 1000 new Items
var list = this.props.list.map(item => {
return <Item key={item.key} item={item} />;
});
return <div>{list}</div>;
}
}
class Item extends React.Component {
shouldComponentUpdate() {
// here I comparing old state/props with new
}
render() {
// some rendering here...
}
}
Run Code Online (Sandbox Code Playgroud)
使用相对较长的列表映射()需要大约10-20ms,我可以注意到界面中的小延迟.
每当我只需要更新一个时,我可以阻止重新创建1000个React对象吗?
xia*_*406 18
您可以使用任何状态管理库来执行此操作,以便在添加新内容时Parent不会跟踪this.state.list=>您List唯一的重新呈现Item.个人Item将在更新时重新呈现.
让我们说你用redux.
你的代码会变成这样:
// Parent.js
class Parent extends React.Component {
render() {
return <List />;
}
}
// List.js
class List extends React.Component {
render() {
var list = this.props.list.map(item => {
return <Item key={item.key} uniqueKey={item.key} />;
});
return <div>{list}</div>;
}
}
const mapStateToProps = (state) => ({
list: getList(state)
});
export default connect(mapStateToProps)(List);
// Item.js
class Item extends React.Component {
shouldComponentUpdate() {
}
render() {
}
}
const mapStateToProps = (state, ownProps) => ({
item: getItemByKey(ownProps.uniqueKey)
});
export default connect(mapStateToProps)(Item);
Run Code Online (Sandbox Code Playgroud)
当然,你必须实现reducer和两个选择器getList和getItemByKey.
有了这个,List如果添加了新元素,或者如果你改变了item.key(你不应该改变),你将重新渲染你的触发器
编辑:
我的初始建议仅解决了渲染列表可能的效率改进问题,并没有解决由于列表更改而限制组件重新渲染的问题.
请参阅@ xiaofan2406的答案,以获得原始问题的清晰解决方案.
有助于使渲染长列表更有效和简单的库:
当你更改数据时,react 默认操作是渲染所有子组件,并创建虚拟 dom 来判断哪个组件需要重新渲染。
所以,如果我们能让 react 知道只有一个组件需要重新渲染。它可以节省时间。
您可以shouldComponentsUpdate在列表组件中使用。
如果在这个函数中返回false,react不会创建虚拟dom来判断。
我假设你的数据是这样的 [{name: 'name_1'}, {name: 'name_2'}]
class Item extends React.Component {
// you need judge if props and state have been changed, if not
// execute return false;
shouldComponentUpdate(nextProps, nextState) {
if (nextProps.name === this.props.name) return false;
return true;
}
render() {
return (
<li>{this.props.name}</li>
)
}
}
Run Code Online (Sandbox Code Playgroud)
由于反应只是渲染已更改的组件。因此,如果您只更改一项的数据,则其他项将不会进行渲染。
| 归档时间: |
|
| 查看次数: |
24018 次 |
| 最近记录: |