Skip to content

Why is my React Native bridged component not working? #2948

@chefnobody

Description

@chefnobody

I want to create a simple UIView subclass and then make it available as a React Native JavaScript component via bridging to React Native. I have followed these directions and thumbed through lots of the react source code: https://facebook.github.io/react-native/docs/native-components-ios.html

Unfortunately, I don't know where my React Native component is failing. This is my Obj-C manager class:

// header
#import "RCTViewManager.h"
#import "ColorPicker.h"

@interface ColorPickerManager : RCTViewManager

@end

// implementation
#import "ColorPickerManager.h"

@interface ColorPickerManager()

@property (nonatomic) ColorPicker * colorPicker;

@end

@implementation ColorPickerManager

RCT_EXPORT_MODULE()

- (instancetype)init {
    self = [super init];
    if ( self ) {
        NSLog(@"color picker manager init");
    self.colorPicker = [[ColorPicker alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    }
    return self;
}

- (UIView *)view {
    NSLog(@"color picker manager -view method");
    return self.colorPicker;
}

@EnD

Here is my simple UIView subclass that I vend via the above -view method:

// header
#import <UIKit/UIKit.h>

@interface ColorPicker : UIView

@end

// implementation
#import "ColorPicker.h"

@interface ColorPicker()

@property (nonatomic) NSArray * colors;

@end

@implementation ColorPicker

- (instancetype)init {
    NSLog(@"init");
    self = [super init];
    if ( self ) {
       [self setUp];
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
    NSLog(@"init with frame: %@", NSStringFromCGRect(frame));
    self = [super initWithFrame:frame];
    if ( self ) {
        [self setUp];
    }
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    NSLog(@"init with coder: %@", aDecoder);
   self = [super initWithCoder:aDecoder];
   if ( self ) {
       [self setUp];
   }
   return self;
}

- (void)setUp {
    self.colors = @[[UIColor redColor], [UIColor greenColor], [UIColor blueColor]];
    self.backgroundColor = self.colors[0];
}

- (void)layoutSubviews {
    NSLog(@"layout subviews");
}

@end

Finally, here's my react component being bridged over to JavaScript:

var { requireNativeComponent } = require('react-native');
var ColorPicker = requireNativeComponent('ColorPicker', null);
module.exports = ColorPicker;
debugger;

And it's declaration and render to the screen:

'use strict';
var React = require('react-native');
var ColorPicker = require('./BridgedComponents/ColorPicker.js');


var {
  StyleSheet
} = React;

var iOS = React.createClass({

    render: function() {
        debugger;
        return (
            <ColorPicker style={styles.container} />
        );
    }
});

var styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
    },
});

AppRegistry.registerComponent('iOS', () => iOS);

This results in nothing rendering to the screen when I expect to see a 100x100 red square. What I have tried:

  • I've added some border color and width to the ColorPicker to ensure that it is rendering something. It has a zero height/width, but I specify a 100x100 sized frame when I create the view.
  • I've verified that my UIView will render exactly what I expect if I remove all React Native code from the project and by putting this view as a subview of a different rootViewController.
  • I have stepped through the debugger in both Xcode and Chrome to verify that the component's manager class initializes and vends the view. (This happens twice, by the way, probably because of reloading, but that still seems inefficient).
  • I have stepped through all the bridging code as well to ensure that my module has been registered and vends its view to the list of bridged modules.
  • I have verified that ColorPicker in my main .js file is not undefined at the time its rendered to screen and when its created via debugger.
  • I have tried applying a style of height: 100, width: 100 to the rendered ColorPicker but it still doesn't show a red squARE

Questions for RN Gurus

  • What else can I do to verify that my view is correctly bridged?
  • Is there anything I should look for in the Chrome Debugger when inspecting these instances to verify that the view was set up correctly?
  • I've tried following some of the source code in the repo but I'm still new to React and I'm not 100% how its all working.
  • When I create a bridged component am I expected to set the appearance and layout in the Obj-C/Swift class or is it better to do that in JavaScript with CSS. Seems to me the former would be expected.

Any help/advice will be greatly appreciated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Ran CommandsOne of our bots successfully processed a command.Resolution: LockedThis issue was locked by the bot.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions