使用SegmentedControllIOS
实施ListView
的最佳做法是什么?我尝试了三种解决方案,所有示例都包含SegmentedControllIOS
,其中包含两个段和两个ListView
。我邀请您讨论这三个的表现(也许有人可以提出其他更好的解决方案)。从我的角度来看,示例是从最有效的顺序给出的。
class Example extends Component {
constructor(props) {
super(props);
this.state = {
ds1: new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2,}),
ds2: new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2,}),
index: 0,
};
}
render() {
return (
<View>
<SegmentedControlIOS
selectedIndex={this.state.index}
values={['ds1', 'ds2']}
onChange={() => this.setState({index: (this.state.index+1)%2})}
/>
<ListView dataSource={this.state.index ? this.state.ds2 : this.state.ds1} />
</View>
);
}
}
class Example extends Component {
constructor(props) {
super(props);
this.state = {
ds1: new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2,}),
ds2: new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2,}),
index: 0,
};
}
render() {
return (
<View>
<SegmentedControlIOS
selectedIndex={this.state.index}
values={['ds1', 'ds2']}
onChange={() => this.setState({index: (this.state.index+1)%2})}
/>
{this.state.index === 0 ?
(<ListView dataSource={this.state.ds1} />)
:
(<ListView dataSource={this.state.ds2} />)
}
</View>
);
}
}
class Example extends Component {
constructor(props) {
super(props);
this.state = {
ds: new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2,}),
ds1: ['some', 'data'],
ds2: ['some', 'other', 'data'],
index: 0,
};
this.onChange = this.onChange.bind(this);
}
onChange() {
this.setState({
ds: this.state.ds.cloneWithRows(this.state.index ? this.ds1 : this.ds2),
index: (this.state.index+1)%2,
})
}
render() {
return (
<View>
<SegmentedControlIOS
selectedIndex={this.state.index}
values={['ds1', 'ds2']}
onChange={this.onChange}
/>
<ListView dataSource={this.state.ds} />
</View>
);
}
}
答案 0 :(得分:0)
第三种方式将是最好的。当您使用cloneWithRows
时,ListView
会使用DataSource
&#39; rowHasChanged
函数来了解现在需要重新渲染的行。由于'some'
的第一行中的ds1
将与'some'
的第一行中的ds2
匹配,因此该行不会被重新呈现。
如果案例1中你没有利用DataSource
对象的状态,ListView
会发现它正在尝试渲染完全不同的(可能是非 - 可比较的)数据源。
在案例2中,您可以通过切换重量级可滚动组件来获得一些有趣的渲染工件。
答案 1 :(得分:0)
我认为这取决于用例
IMO,我会选择 opt2 开始,因为它很容易调试,如果有任何性能问题,我会选择 opt1(还要检查 FlatList 是如何实现的:https://reactnative.dev/docs/optimizing-flatlist-configuration)。我觉得opt1和opt3会导致list1渲染list2的数据,反之亦然
我认为,我们很少需要在第一次渲染大量行。通常,我们使用分页(或滚动到底部时持续加载),通过这种加载,当您切换段时,数据会刷新,您不必渲染大量行。
opt2 的优点是:
有问题我可能会去 opt1,因为在 opt2 上,切换选项卡时整个列表会重新挂载,这不好(实际上,我们可以隐藏列表而不是卸载它,会消耗更多内存,但渲染速度更快)
而且性能仍然很差,我会考虑在本地实现它 :D