React Native-组件的引用

作者: 于连林520wcf | 来源:发表于2016-08-27 17:33 被阅读5271次

    之前文章中,我们使用了许多React Native组件,也定义了一些组件。但是我们都没有定义组件的标识,我们都是通过回调方法处理组件对应的事件,这种情况能满足绝大多数需求,有些情况我们需要对组件进行操作,此时就需要获取组件的引用,进而通过该应用对组件进行操作。比如,我们可以通过引用拿到组件,修改组件的属性。

    定义组件的引用

    通过在JSX代码中加入 ref="某个字符串",就可以定义一个组件的引用名称,如:

    <TextInput ref="textInputRefer"
        ...
    />
    

    通过 this.refs.textInputRefer就可以得到这个组件的引用。
    还可以调用组件里的公开函数:

    this.refs.aReferName.公开成员函数名()
    

    重新设定组件的属性

    每一个React Native 组件都有一个公开的成员函数setNativeProps,它可以增加或者修改React Native组件的属性。

    但是不建议使用setNativeProps函数,就因为它太简单粗暴了,它可以直接操作任何层面的组件属性,而不是使用React Native组件的状态机变量,这样会使代码逻辑混乱,可能打乱原来设计编写好的业务逻辑。
    在使用之前还是先尝试使用setState和shouldComponentUpdate方法来解决问题。

    在不得不频繁刷新,同时避免渲染组件结构和同步太多的视图变化带来的大量开销时,才考虑使用setNativeProps函数。

    示例代码:

    ...
    class AwesomeProject extends Component {
        // 构造
        constructor(props) {
            super(props);
            // 初始状态
            this.state = {
                textInputValue: ''
            };
            this.buttonPressed = this.buttonPressed.bind(this);
        }
    
        buttonPressed() { //当按钮按下的时候执行此函数
            let textInputValue = 'new value';
            this.setState({textInputValue});
            //修改文本输入框的属性值
            this.refs.textInputRefer.setNativeProps({
                editable:false
            });
            this.refs.text2.setNativeProps({
                style:{
                    color:'blue',
                    fontSize:30
                }
            });
            //使文本输入框变为不可编辑
        }
    
        render() {
            return (
                //ref={'text2'}>   //指定本组件的引用名
                <View style={styles.container}>
                    <Text style={styles.buttonStyle}
                          onPress={this.buttonPressed}>
                        按我
                    </Text>
                    <Text style={styles.textPromptStyle}
                          ref="text2">
                        文字提示
                    </Text>
                    <View>
                        <TextInput style={styles.textInputStyle}
                                   ref="textInputRefer"
                                   value={this.state.textInputValue}
                                   onChangeText={(textInputValue)=>this.setState({textInputValue})}/>
                    </View>
                </View>
            );
        }
    }
    
    const styles = StyleSheet.create({
        container: {
            flex: 1,
            justifyContent: 'center',
            alignItems: 'center'
        },
        buttonStyle: { //文本组件样式,定义简单的按钮
            fontSize: 20,
            backgroundColor: 'grey'
        },
        textPromptStyle: { //文本组件样式
            fontSize: 20
        },
        textInputStyle: { //文本输入组件样式
            width: 150,
            height: 50,
            fontSize: 20,
            backgroundColor: 'grey'
        }
    });
    
    ...
    
    

    当按钮点击的时候就会修改属性,让TextInput组件不能再编辑,让字体变大,这个操作最好通过setState完成, 上面的做法只是为了给大家演示如何修改属性。

    测量控件measure

    使用View组件的onLayout回调函数是获取组件的宽,高与位置信息的最好办法,但是有时候组件是代码生成的,只能使用组件的measure成员函数测量控件了,这时候就需要根据组件的引用去调用组件的measure函数

    下面代码不是通过代码生成的组件,主要是为了演示通过组件的引用调用measure函数。

    ...
    class AwesomeProject extends Component {
        // 构造
        constructor(props) {
            super(props);
            // 初始状态
            this.state = {};
            this.tempfunc = this.tempfunc.bind(this);
            this.getPosition = this.getPosition.bind(this);
        }
    
        componentDidMount() {
           // this.tempfunc();
            //在componentDidMount执行完后才可以获取位置,不能直接调用tempfunc函数
           var aref = this.tempfunc;
            //这个位置保险起见延迟1毫秒,其实把数字改成0默认也在componentDidMount之后执行
            window.setTimeout(aref, 1);//延迟一毫秒执行tempfuc
        }
    
        tempfunc() {
            //测量 获取位置, 参数是回调方法
            this.refs.textInputRefer.measure(this.getPosition)
        }
    
        getPosition(fx, fy, width, height, px, py) {
            console.log('getPosition');
            console.log("width:" + width); //控件宽
            console.log("height:" + height);//控件高
            console.log("fx:" + fx); //距离父控件左端 x的偏移量
            console.log("fy:" + fy); //距离父控件上端 y的偏移量
            console.log("px:" + px); //距离屏幕左端 x的偏移量
            console.log("py:" + py); //距离屏幕上端 y的偏移量
        }
    
        render() {
            return (
                // 为了保重TextInput组件居中显示多用一个View包裹
                <View style={styles.container}>
                    <View style={{borderWidth:1}}>
                        <TextInput style={styles.textInputStyle}
                                   ref="textInputRefer"
                                   value={this.state.textInputValue}
                                   onChangeText={(textInputValue)=>this.setState({textInputValue})}/>
                    </View>
                </View>
    
            );
        }
    }
    
    const styles = StyleSheet.create({
        container: {
            flex: 1,
            justifyContent: 'center',
            alignItems: 'center'
        },
        textInputStyle: { //文本输入组件样式
            width: 200,
            height: 55,
            fontSize: 50,
            alignItems: 'center',
            justifyContent: 'center',
            paddingTop: 0,
            paddingBottom: 0,
            backgroundColor: "blue"
        }
    });
    ...
    
    运行结果

    更多精彩请关注微信公众账号likeDev,公众账号名称:爱上Android。


    likeDev.jpg

    相关文章

      网友评论

      • 勿问情殇:我在 FlatList 组件中,用了这个 measure 方法,但是说 cannot read property 'measure' of undefined
        mf168:解决了么
      • 封印命运:感谢楼主,测量组件位置很有用,学到了

      本文标题:React Native-组件的引用

      本文链接:https://www.haomeiwen.com/subject/icftettx.html