镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Query for child components [JS -> ObjC binding] #126

Description

@jaygarcia

If I wanted to get a reference to the underlying Component for a Touchable child, how does one do this?

<TouchableHighlight underlayColor="rgb(210, 230, 255)" onPress={this.onPress}>
    <Text>ClickMe</Text>
</TouchableHighlight>

I've read
http://facebook.github.io/react/tips/communicate-between-components.html

... but it very much speaks to the data that represents the div, not the div itself.

How do i get a reference to the actual JavaScript -> ObjC binding node for the Text element above in this.onPress?

Activity

  1. changed the title [-]Query for child components[/-] [+]Query for child components [JS -> ObjC binding][/+] on Mar 5, 2015
  2. vjeux commented on Mar 5, 2015

    @vjeux
    Contributor

    What is your end goal?

    To your question, the facility with React is called ref. But in this case I have a feeling that it's not the solution you are looking for. http://facebook.github.io/react/docs/more-about-refs.html

    this.refs[refKey].getNodeHandle()
    
  3. jaygarcia commented on Mar 5, 2015

    @jaygarcia
    ContributorAuthor

    Background:
    I'm building a React Native Videogame music player as a demo application.

    I'd like to be able to do things like disable/enable the rendering of Audio waveforms via tap of the waveform view instance. Rather than destroy the waveform view when tapped, i'd rather set a boolean that stops the waveform from rendering.

    My thoughts is to bind a onPress event inside of the ReactJS implementation of the custom UI view, but UIView doesn't respond to taps natively. So, the only way to listen to taps using the React iOS API is to wrap my custom view w/ a Touchable component.

    I can setup onPress via Touchable, but I need to somehow get a reference to the child that Touchable is wrapping to disable the rendering of the waveform.

    Now, I could listen for tap events on the custom waveform UI view, but that feels like cheating :(

  4. vjeux commented on Mar 5, 2015

    @vjeux
    Contributor

    Oh I see, you want to integrate with an Obj-c component. Then yeah, ref and getNodeHandle() is the right way to do it.

  5. sahrens commented on Mar 7, 2015

    @sahrens
    Contributor

    If you're just enabling disabling, you should do it with a prop:
    <TouchableHighlight onPress={()=>this.setState({enabled: !this.state.enabled})}>

    Then map the enabled prop through to your native view, and run whatever native code you want in the setEnabled: setter. Maybe take a look at RCTNetworkImageView(Manager).m

    -Spencer

    On Mar 5, 2015, at 12:37 PM, Christopher Chedeau notifications@github.com wrote:

    Oh I see, you want to integrate with an Obj-c component. Then yeah, ref and getNodeHandle() is the right way to do it.

    —
    Reply to this email directly or view it on GitHub.

  6. jaygarcia commented on Mar 11, 2015

    @jaygarcia
    ContributorAuthor

    RCTNetworkImageView no longer has a manager, from what I can tell.

    What i'm trying to achieve:

    From the context of whatever class is the result of React.createClass(), where the render function returns below:

            return (
                <View style={styles.container}>
                    <View style={styles.titleBar}>
                        <Text style={{fontSize: 20}}>{gameObj.game}</Text>
                    </View>
    
                    <ScrollView horizontal={true} style={styles.imageContainer} pagingEnabled={true} centerContent={true}>
                        {images}
                    </ScrollView>
    
                    <View style={styles.vizContainer}>
                        <RCEzAudioPlotGlView style={styles.vizItem}/>
                        <RCEzAudioPlotGlView style={styles.vizItem}/>
                    </View>
    
                    <View style={styles.controlsContainer}>
                        <Text style={styles.timeText}>
                            Current Time : {state.currentTime}
                        </Text>
                        <Text style={styles.trackText}>
                            {state.currentTrack + 1}  of {gameObj.trackCount + 1}
                        </Text>
                        <ControlButton onPress={this.onButtonPress} btnChar={"prev"} btnStyle={"prevButton"}/>
                        <ControlButton onPress={this.onButtonPress} btnChar={centerBtnChar} btnStyle={centerBtnStyle}/>
                        <ControlButton onPress={this.onButtonPress} btnChar={"next"} btnStyle={"nextButton"}/>
                    </View>                     
                </View>
            );
    

    I'd like to gain access to the RCEzAudioPlotGlView instances and send an array of floating points to them to render sound waves.

    Now, I've /kinda/ gotten a foothold of them via the following really ugly code.
    ---side note, i've tried to use getNativeNode() or getNodeHandle() and those seem to return integers, which confuses me :P

        onButtonPress : function(buttonType) {
            // var o = this._renderedComponent._renderedChildren['.3']._renderedChildren['.2'];
            var viewContainer = this._reactInternalInstance._renderedComponent._renderedComponent._renderedChildren['.2'],
                children      = viewContainer._renderedComponent._renderedChildren,
                leftViz       = children['.0'],
                rightViz      = children['.1'];
    
            leftViz._instance.something()
            debugger;
            var methodName = this.methodMap[buttonType];
            this[methodName] && this[methodName]();
        },
    

    the leftViz & rightViz JS references basically put me within the context of the module in which i've defined RCEzPlotGlView (below).

    var View = React.createClass({
        statics : {
            pointerEvents: StyleConstants.PointerEventsValues,
            stylePropType
        },
    
        mixins: [NativeMethodsMixin],
    
        /**
        * `NativeMethodsMixin` will look for this when invoking `setNativeProps`. We
        * make `this` look like an actual native component class.
        */
        viewConfig: {
            uiViewClassName: 'RCEzPlotGlView',
            validAttributes: ReactIOSViewAttributes.RKView
        },
    
        render: function() {
            return <RCEzPlotGlView {...this.props} />;
        },
        something : function() {
            console.log('stopped')
            debugger;
        }
    });
    
    var RCEzPlotGlView = createReactIOSNativeComponentClass({
        validAttributes: ReactIOSViewAttributes.RKView,
        uiViewClassName: 'RCEzPlotGlView',
    });
    

    What i'm missing is how to get from the ReactJS class to Objective C land for that particular instance. Inspecting this.refs results in an empty object.

    refs

  7. jaygarcia commented on Mar 14, 2015

    @jaygarcia
    ContributorAuthor

    I believe that I've gotten a step closer by inspecting the RCStaticImageManager.m source:

    I suppose I was looking for directly calling functions like with what the RC_EXPORT() macro does for managers.

    The RCT_CUSTOM_VIEW_PROPERTY macro seems to be the right way to go a la the example below:

    RCT_CUSTOM_VIEW_PROPERTY(imageTag, RCTStaticImage *)
    {
      if (json) {
        [RCTImageLoader loadImageWithTag:[RCTConvert NSString:json] callback:^(NSError *error, UIImage *image) {
          if (error) {
            RCTLogWarn(@"%@", error.localizedDescription);
          } else {
            view.image = image;
          }
        }];
      } else {
        view.image = defaultView.image;
      }
    }
    
  8. sahrens commented on Mar 14, 2015

    @sahrens
    Contributor

    Yes, you should just use props when possible.

    The handles are meant to be opaque references so the value/contents should be irrelevant from a JS perspective. You can pass them over the bridge to native and native can use them to find the corresponding native element. One example where this is done is the scrollTo method on RCTScrollViewManager.

    -Spencer

    On Mar 14, 2015, at 10:31 AM, Jay Garcia notifications@github.com wrote:

    I believe that I've gotten a step closer by inspecting the RCStaticImageManager.m source:

    I suppose I was looking for directly calling functions like with what the RC_EXPORT() macro does for managers.

    The RCT_CUSTOM_VIEW_PROPERTY macro seems to be the right way to go a la the example below:

    RCT_CUSTOM_VIEW_PROPERTY(imageTag, RCTStaticImage *)
    {
    if (json) {
    [RCTImageLoader loadImageWithTag:[RCTConvert NSString:json] callback:^(NSError *error, UIImage *image) {
    if (error) {
    RCTLogWarn(@"%@", error.localizedDescription);
    } else {
    view.image = image;
    }
    }];
    } else {
    view.image = defaultView.image;
    }
    }
    —
    Reply to this email directly or view it on GitHub.

  9. jaygarcia commented on Mar 14, 2015

    @jaygarcia
    ContributorAuthor

    Thanks @sahrens. I've gotten tot he point where a view Mgr can execute methods on view instances.

    Now it's time to see how well this thing deals with 512 floating point audio samples =) per channel at 30fps.

  10. sahrens commented on Mar 14, 2015

    @sahrens
    Contributor

    If you batch it up, I bet it won't be a problem :)

    -Spencer

    On Mar 14, 2015, at 11:34 AM, Jay Garcia notifications@github.com wrote:

    Thanks @sahrens. I've gotten tot he point where a view Mgr can execute methods on view instances.

    Now it's time to see how well this thing deals with 512 floating point audio samples =) per channel at 30fps.

    —
    Reply to this email directly or view it on GitHub.

  11. jaygarcia commented on Mar 14, 2015

    @jaygarcia
    ContributorAuthor

    ... slowly ... but ... surely ...
    (This is just random data)

    2015-03-14_19-45-57

  12. jaygarcia commented on Mar 15, 2015

    @jaygarcia
    ContributorAuthor

    Getting a lot closer. Timing needs to be adjusted. Seems that making the round trip from objc -> JS -> objc of 1024 floats was way too slow. Now the visualizers actually query the singleton themselves for the buffer data so it's objc -> objc and lighting fast.

    http://youtu.be/lTqo0iAQ4Gc

  13. jaygarcia commented on Mar 16, 2015

    @jaygarcia
    ContributorAuthor

    I'm going to close this thread. The only thing I'm going to add before I close it is that this really needs to be documented =). I've gotten things to work but it's hard for me to know if what i've implemented are hacks or the right patterns. :P

  14. locked as resolved and limited conversation to collaborators on May 29, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions