react native

React Navite踩坑日记)(五) —— FlatList

2017-08-28  本文已影响133人  黑羽肃霜
效果图.gif

参考文章

理解

同样类比于我们iOSTableView,我们初始化一个TableView,需要对下面这几个代理做处理

相比于上面的四个delegateRN中用了一个renderItem来囊括。

renderItem

renderItem={({item}) => this._renderItem(item)}


下面是这个组件的参考代码

class PaywayOptions extends Component {
    constructor(props) {
        super(props);
        this.state = {selectedIndex: -1};
    }

    _renderItem(item) {
        let whetherSel = (this.state.selectedIndex === item.index);//
        return <TouchableHighlight style={[styles.PaywayContainer, {backgroundColor: whetherSel ? 'blue' : 'white'}]}
                                   onPress={() => {
                                       if (whetherSel === false) {
                                           console.log('选中' + item.index);
                                           this.setState({selectedIndex: item.index})
                                       }
                                   }}>
            <Text style={{width: 50, height: 18, color: 'black'}}>{item.key}</Text>
        </TouchableHighlight>
    };

    _seperator(){
        return <View style={{backgroundColor:'black',height:1,width:width-60}}/>
    }

    render() {
        return (
            <View style={{height: 126, width: width - 40, backgroundColor: 'yellow', alignSelf: 'center'}}>
                <FlatList data={[{key: 'a', index: 0}, {key: 'b', index: 1}]}
                          renderItem={({item}) => this._renderItem(item)}
                          keyExtractor={(item) => item.index}
                          ItemSeparatorComponent = {this._seperator.bind(this)}
                />
            </View>
        )

    }
}

Data 赋值问题讨论。

先来看下面两张图,是data赋值不同时造成的。

可行的.gif 不可行的.gif

下面是代码片段

// ...
    fetchData() {
        return [{image: unionpayIco, width: 30, height: 20, title: '银联支付', index: 0},
            {image: wechatpayIco, width: 26, height: 24, title: '微信支付', index: 1},
            {image: alipayIco, width: 25, height: 24, title: '支付宝支付', index: 2},
        ];
    }

    _data = [{image: unionpayIco, width: 30, height: 20, title: '银联支付', index: 0},
        {image: wechatpayIco, width: 26, height: 24, title: '微信支付', index: 1},
        {image: alipayIco, width: 25, height: 24, title: '支付宝支付', index: 2},
    ];

    _renderItem(item) {
        let whetherSel = (this.state.selectedIndex === item.index);//
        return (
            <TouchableOpacity style={[styles.optionContainer, {backgroundColor: whetherSel ? '#EAF3FF' : '#FDFFFD'}]}
                              activeOpacity={0.5}
                              onPress={() => {
                                  console.log('当前idx = ' + item.index);
                                  console.log('当前state idx = ' + this.state.selectedIndex);
                                  if (whetherSel === false) {
                                      console.log('是否设置');
                                      this.setState({selectedIndex: item.index})
                                  }
                              }}>
                <View style={styles.imageContainer}>
                    <Image style={{width: item.width, height: item.height}} source={item.image}/>
                </View>
                <Text style={styles.text}>{item.title}</Text>
                <Image style={{width: 20, height: 20, marginRight: 10}} source={whetherSel ? markedIco : unmarkedIco}/>
            </TouchableOpacity>
        )
    }

    render() {
        return (
            <View style={{height: 126, width: width - 40, alignSelf: 'center', marginTop:this.props.topDistance}}>
                <FlatList data= {this._data}//{this.fetchData()}
                          renderItem={({item}) => this._renderItem(item)}
                          keyExtractor={(item) => item.index}
                          scrollEnabled={false}
                />
            </View>
        );
    }

如果使用 fetchData(),这个返回JSON数组的函数,传值给FlatList,结果是没有问题的。
但是如果用一个变量去存储data就会出现右边那张图显示的样子。
出现这种情况的原因是,作为数据变量的 data不可以就这样写在这个位置。正确的写法,是在构造函数constructor中去指定一个变量 this.data = []
才可以(不要使用这种错误的写法!)

———— 2018.3.13补充 ——————

概述

经过一阵子对 FlatList的使用,总结了以下几个小点.

FlatList 不要尝试去实现局部刷新

这点理解起来其实有点费解。

DataSource 不要像上面那样写

作为数据,dataSource 建议是写在state里头,方便管理。原因其实也包括上面的这条了。
另外就是,如果数据源有改变,不要做下面这样的代码写法, 因为这样写,是不会触发render 刷新的!

let tempArray = this.state.dataSource;
tempArray.push({content:'xxx'});
this.setState({dataSource:tempArray})

因为数组的赋值,如果直接使用简单的等号,只会讲指针传过来。换言之,这是一个浅拷贝操作。
正确的写法是:

let tempArray = [...this.state.dataSource];
tempArray.push({content:'xxx'});
this.setState({dataSource:tempArray})
上一篇 下一篇

猜你喜欢

热点阅读