TouchableOpacity和TouchableHighlight对setNativeProps的使用因果求解释
-
在学习使用setNativeProps的时候,发现TouchableOpacity和TouchableHighlight对其支持有偏差,JS刚入门,求大神解释
/** * Sample React Native App * https://github.com/facebook/react-native */ 'use strict'; var React = require('react-native'); var keyOf = require('keyOf'); var { AppRegistry, StyleSheet, Text, View, TouchableOpacity, TouchableHighlight, TextInput, } = React; var MyButton = React.createClass({ // 对于自定义的复合组件可以对子组件setNativeProps传递进行可选配置 setNativeProps(nativeProps) { this._root.setNativeProps(nativeProps); this._child.setNativeProps(nativeProps); }, render() { return ( <View {...this.props} ref={component => this._root = component} style={{padding:20,width:300,height:50,backgroundColor:'gray'}}> <Text ref={component => this._child = component}>{this.props.label}</Text> </View> ) }, }); var WalletReact = React.createClass({ clearText() { this._textInput.setNativeProps({text: ''}); // TouchableOpacity setNativeProps 应用在子节点 // this._btn.setNativeProps({style:{width:50}}); // 日志输出 undefined is not an object (evaluating 'this.viewConfig.validAttributes') console.log("this._btn:"+this._btn); // 日志输出 this._btn:[object Object] 说明可以引用到 this._btnLable.setNativeProps({style:{backgroundColor:'red'}}); console.log("this._btnLable:"+this._btnLable); // 日志输出 this._btnLable:[object Object] // react-native/Libraries/Components/Touchable/TouchableOpacity.js // return ( // <Animated.View // accessible={true} // accessibilityComponentType={this.props.accessibilityComponentType} // accessibilityTraits={this.props.accessibilityTraits} // style={[this.props.style, {opacity: this.state.anim}]} // testID={this.props.testID} // onLayout={this.props.onLayout} // onStartShouldSetResponder={this.touchableHandleStartShouldSetResponder} // onResponderTerminationRequest={this.touchableHandleResponderTerminationRequest} // onResponderGrant={this.touchableHandleResponderGrant} // onResponderMove={this.touchableHandleResponderMove} // onResponderRelease={this.touchableHandleResponderRelease} // onResponderTerminate={this.touchableHandleResponderTerminate}> // {this.props.children} // </Animated.View> // TouchableOpacity源码显示最外层的View为Animated.View // Animated.View是对原始View进行了动画初始化 //react-native/Libraries/Animated/src/Animated.js // var View = require('View'); // module.exports = { // ...AnimatedImplementation, // View: AnimatedImplementation.createAnimatedComponent(View), ///react-native/Libraries/Animated/src/AnimatedImplementation.js // 初始化的过程中对View进行了ref设置,和setNativeProps进行了配置 // 即对refName为'node'的元素进行了setNativeProps进行了配置 // var refName = 'node'; // setNativeProps(props) { // this.refs[refName].setNativeProps(props); // } // render() { // return ( // <Component // {...this._propsAnimated.__getValue()} // ref={refName} // /> // ); // } // ); // 尝试通过字符串方式引用 console.log("this._btn:"+this.refs['node']); // 日志输出 this._btn:[object Object] 说明可以引用到 // this.refs['node'].setNativeProps({style:{backgroundColor:'green'}}); // 日志输出 undefined is not an object (evaluating 'this.viewConfig.validAttributes') // 还是失败,看到错误发生在 // react-native/Libraries/ReactIOS/NativeMethodsMixin.js // setNativeProps: function(nativeProps: Object) { // if (__DEV__) { // warnForStyleProps(nativeProps, this.viewConfig.validAttributes); // } // var updatePayload = ReactNativeAttributePayload.create( // nativeProps, // this.viewConfig.validAttributes // ); // UIManager.updateView( // findNodeHandle(this), // this.viewConfig.uiViewClassName, // updatePayload // ); // }, // __DEV__ 出自以下,没看懂,求解释 // var invariant = require('invariant'); // var __DEV__ = process.env.NODE_ENV !== 'production';**** // TouchableHighlight setNativeProps 应用在根节点TouchableHighlight上 this._btn1.setNativeProps({style:{backgroundColor:'green'}}); // this._btnLable1.setNativeProps({style:{backgroundColor:'red'}}); // undefined is not an object (evaluating 'this._btnLable1.setNativeProps') // 因为对于子节点的无法引用 console.log("this._btnLable1:"+this._btnLable1); // 日志输出 this._btnLable1:undefined // 查看源码 // react-native/Libraries/Components/Touchable/TouchableHighlight.js // <View // accessible={true} // accessibilityComponentType={this.props.accessibilityComponentType} // accessibilityTraits={this.props.accessibilityTraits} // ref={UNDERLAY_REF} // style={this.state.underlayStyle} // onLayout={this.props.onLayout} // onStartShouldSetResponder={this.touchableHandleStartShouldSetResponder} // onResponderTerminationRequest={this.touchableHandleResponderTerminationRequest} // onResponderGrant={this.touchableHandleResponderGrant} // onResponderMove={this.touchableHandleResponderMove} // onResponderRelease={this.touchableHandleResponderRelease} // onResponderTerminate={this.touchableHandleResponderTerminate} // testID={this.props.testID}> // // {React.cloneElement( // onlyChild(this.props.children), // { // ref: CHILD_REF, // } // )} // </View> // 可以看到TouchableHighlight只是一个普通的View,children却是通过React.cloneElement,并且设置了引用 // var CHILD_REF = keyOf({childRef: null}); console.log('CHILD_REF '+keyOf({childRef: null})); // 日志输出 CHILD_REF childRef // this.refs['childRef'].setNativeProps({style:{backgroundColor:'red'}}); // 日志输出 undefined is not an object (evaluating 'this.refs['childRef'].setNativeProps') // 凌乱了???有跟不下去了 // 综上只能理解到 // TouchableOpacity setNativeProps 应用在子节点,但是可以引用到根节点 // TouchableHighlight setNativeProps 应用在根节点TouchableHighlight上,引用不到子节点 this._lable.setNativeProps({style:{backgroundColor:'green'}}); this._lable.setNativeProps({value:'Text has change Text'}); this._view.setNativeProps({style:{backgroundColor:'green'}}); this._btnView.setNativeProps({style:{backgroundColor:'green'}}); }, render() { return ( <View style={styles.container}> <TextInput ref={component => this._textInput = component} style={{margin:20,height:50,width:300,borderWidth:1,borderColor:'#888888'}} text='12332' /> <TouchableOpacity ref={label1 => this._btn = label1} style={{margin:20,backgroundColor:'gray'}} onPress={this.clearText}> <Text ref={label => this._btnLable = label} style={{margin:20}} >TouchableOpacity Child </Text> </TouchableOpacity > <TouchableOpacity ref={'node'} style={{margin:20}} onPress={this.clearText}> <Text ref={label => this._btnLable2 = label} style={{margin:20}} >TouchableOpacity Child </Text> </TouchableOpacity > <TouchableHighlight style={{margin:20}} ref={label => this._btn1 = label} onPress={this.changeProps}> <Text ref={label => this._btnLable1 = label} style={{margin:20}} >TouchableHighlight Child</Text> </TouchableHighlight > <TouchableHighlight style={{margin:20}} ref={label => this._btn2 = label} onPress={this.changeProps}> <Text ref={'TouchableHighlight'} style={{margin:20}} >TouchableHighlight Child</Text> </TouchableHighlight > <Text ref={label => this._lable = label} style={{margin:20}} >Text</Text> <View ref={label => this._view = label} style={{margin:20}}><Text>View</Text></View> <MyButton style={{margin:20}} ref={component => this._btnView = component} label='MyButton'></MyButton> </View> ); } }); var styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, welcome: { fontSize: 20, textAlign: 'center', margin: 10, }, instructions: { textAlign: 'center', color: '#333333', marginBottom: 5, }, }); AppRegistry.registerComponent('WalletReact', () => WalletReact);