Repository navigation
Query for child components [JS -> ObjC binding] #126
Description
Activity
- changed the title
[-]Query for child components[/-][+]Query for child components [JS -> ObjC binding][/+]on Mar 5, 2015 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.htmlthis.refs[refKey].getNodeHandle()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 :(
Oh I see, you want to integrate with an Obj-c component. Then yeah, ref and getNodeHandle() is the right way to do it.
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.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 :PonButtonPress : 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.
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; } }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.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.
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.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.
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
- locked as resolved and limited conversation to collaborators
on May 29, 2018 - addedResolution: LockedThis issue was locked by the bot.This issue was locked by the bot.
on Jul 23, 2018


If I wanted to get a reference to the underlying Component for a Touchable child, how does one do this?
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?