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