What are the best practices in implementing SegmentedControllIOS
with ListView
? I tried three solutions, all examples contain SegmentedControllIOS
with two segments and two ListView
. I invite you to discuss performance of this three (maybe someone could propose other, better solution). From my perspective examples are given in order from most efficient.
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> ); } }
Third way will be best. When you use cloneWithRows
the ListView
uses the DataSource
's rowHasChanged
function to know what rows it now needs to re-render. Since 'some'
in the first row of ds1
will match 'some'
in the first row of ds2
that row will not be re-rendered.
In case 1 you're not taking advantage of the DataSource
object's state, the ListView
sees that it's trying to render a completely different (possibly non-comparable) data source.
In case 2 you might get some fun rendering artifacts from switching out a heavy weight scrollable component.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With