Javascript React Native-良好实践:带ListView的分段控件

Javascript React Native-良好实践:带ListView的分段控件,javascript,ios,listview,react-native,segmentedcontrol,Javascript,Ios,Listview,React Native,Segmentedcontrol,使用列表视图实施分段控制的最佳实践是什么?我尝试了三种解决方案,所有示例都包含带有两个段和两个ListView的SegmentedControllIOS。我邀请您讨论这三个方面的性能(也许有人可以提出其他更好的解决方案)。从我的角度来看,示例是按照最有效的顺序给出的 1.两个独立的数据源,一个ListView(更改ListView的数据源) 类示例扩展组件{ 建造师(道具){ 超级(道具); 此.state={ ds1:新的ListView.DataSource({rowHasChanged:(

使用
列表视图实施
分段控制的最佳实践是什么?我尝试了三种解决方案,所有示例都包含带有两个段和两个
ListView
SegmentedControllIOS
。我邀请您讨论这三个方面的性能(也许有人可以提出其他更好的解决方案)。从我的角度来看,示例是按照最有效的顺序给出的

1.两个独立的数据源,一个ListView(更改ListView的数据源)
类示例扩展组件{
建造师(道具){
超级(道具);
此.state={
ds1:新的ListView.DataSource({rowHasChanged:(r1,r2)=>r1!==r2,}),
ds2:新的ListView.DataSource({rowHasChanged:(r1,r2)=>r1!==r2,}),
索引:0,
};
}
render(){
返回(
this.setState({index:(this.state.index+1)%2})
/>
);
}
}
2.两个独立的数据源和两个独立的ListView
类示例扩展组件{
建造师(道具){
超级(道具);
此.state={
ds1:新的ListView.DataSource({rowHasChanged:(r1,r2)=>r1!==r2,}),
ds2:新的ListView.DataSource({rowHasChanged:(r1,r2)=>r1!==r2,}),
索引:0,
};
}
render(){
返回(
this.setState({index:(this.state.index+1)%2})
/>
{this.state.index==0?
()
:
()
}
);
}
}
3.一个数据源,变更索引数据源上的cloneWithRows
类示例扩展组件{
建造师(道具){
超级(道具);
此.state={
ds:new ListView.DataSource({rowHasChanged:(r1,r2)=>r1!==r2,}),
ds1:[“一些”,“数据”],
ds2:[“某些”、“其他”、“数据”],
索引:0,
};
this.onChange=this.onChange.bind(this);
}
onChange(){
这是我的国家({
ds:this.state.ds.cloneWithRows(this.state.index?this.ds1:this.ds2),
索引:(this.state.index+1)%2,
})
}
render(){
返回(
);
}
}

第三种方式最好。使用
cloneWithRows
时,
ListView
使用
DataSource
rowHasChanged
函数来知道现在需要重新渲染哪些行。由于
ds1
第一行中的
'some'
将与
ds2
第一行中的
'some'
匹配,因此该行将不会重新渲染

在案例1中,您没有利用
数据源
对象的状态,
列表视图
看到它试图呈现一个完全不同(可能不可比较)的数据源


在案例2中,您可能会从关闭重量级可滚动组件中获得一些有趣的渲染工件

我认为这取决于用例

在我看来,我将选择opt2作为开始,因为它简单且易于调试,如果存在任何性能问题,则选择opt1(同时检查FlatList是如何实现的:)。我觉得opt1和opt3会导致list1呈现list2的数据,反之亦然

我认为,我们很少需要在第一次渲染大量行。通常,我们使用分页(或滚动到底部时的连续加载),通过这种加载,当您切换段时,数据被刷新,您不必渲染大量行

opt2的优点是:

  • 易于理解的代码
  • 处理renderRow和selectRow也更容易,因为您有两个单独的列表
如果有任何问题,我可能会转到opt1,因为在opt2上,切换选项卡时整个列表都会重新装载,这不好(实际上,我们可以隐藏列表而不是卸载它,这会占用更多内存,但渲染速度更快)

并且性能仍然不好,我会考虑在本地方面实施:d

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>
    );
  }
}