React Native - RCT_EXPORT_VIEW_PROPERTY is nil in view init method

2.3k views Asked by At

I am trying to create a Native UI component on my RN project on iOS. I pass a props uri to my Native component. But when I try to use it in the init method of my view, it is nil.

// myNativeComponentManager.m

@implementation myNativeComponentManager

RCT_EXPORT_MODULE()
RCT_EXPORT_VIEW_PROPERTY(uri, NSString *);

- (UIView *)view
{
    return [[myNativeComponentView alloc] init];
}

@end

// myNativeComponentView.m

@implementation myNativeComponentView

- (instancetype)init
{
    self = [super init];

// self.uri is nil here
    NSURL *imageURL = [NSURL URLWithString:self.uri];
    NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
    UIImage *image = [UIImage imageWithData:imageData];

    self.imgView = [[UIImageView alloc] initWithFrame:self.bounds];
    self.imgView.image = image;
    self.imgView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    self.imgView.userInteractionEnabled = YES;
    [self addSubview:self.imgView];

    UITapGestureRecognizer *tap =
    [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTap:)];
    [self.imgView addGestureRecognizer:tap];

    return self;
}

- (void)onTap:(id)sender {
// self.uri is not nil here
    NSLog(self.uri);
}
 @end

uri is nil in the init but not in the onTap method so it makes me think we can't use property in the init method? In that case, how do I initialise my image with this uri? Is there a way to know the view did initialized? I thought about creating a method to set my image and calling it on the JS part in componentDidMount but it feels wrong.

Thanks for your help!

1

There are 1 answers

0
House On

props passed from react native cannot be fetch in init method of native UIView. You should handle it in property setter method.

// react native x.js
export default class EmailSSO extends React.Component {
    render() {
        var credential = {
            username: "abc",
            password: "xyz",
        };
        return (
            <EmailView credential={credential} style={{ flex: 1 }} />
        );
    }
}

// native XXXView.m
- (void)setCredential:(Credential *)credential
{
  _credential = credential;
  NSLog(@"Username is %@", credential.username);
}