I have my own view in the Ignite project. I am trying to customize a message from Objective-C to React Native . A post from React Native to iOS works with HTML injection, but not vice versa. I tried using both RCTBubblingEventBlock and RCTDirectEventBlock , but it does not work. Here is the completeness of my implementation. Of course, I changed the names of the components and simply left an essential implementation for your understanding of what has been done so far:
Objective-C code:
// CustomViewManager.h #import "RCTViewManager.h" @interface CustomViewManager : RCTViewManager @end // CustomViewManager.m #import "CustomViewManager.h" #import "CustomView.h" #import "RCTBridge.h" #import "RCTEventDispatcher.h" #import "UIView+React.h" @implementation CustomViewManager RCT_EXPORT_MODULE() RCT_EXPORT_VIEW_PROPERTY(htmlInjection, NSString) RCT_EXPORT_VIEW_PROPERTY(onEventA, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onEventB, RCTDirectEventBlock) - (UIView *) view { return [CustomView new]; } @end // CustomView.h #import "RCTView.h" @interface CustomView : RCTView @property (nonatomic, assign) NSString *htmlInjection; @property (nonatomic, copy) RCTDirectEventBlock onEventA; @property (nonatomic, copy) RCTDirectEventBlock onEventB; @end // CustomView.m #import "CustomView.h" #import "RCTUtils.h" #import "RCTBridge.h" #import "RCTEventDispatcher.h" #import "UIView+React.h" #import "MyExternalComponent.h" @interface CustomView () <UIWebViewDelegate> @property (nonatomic, strong) UIWebView* webView; @end - (void) setUpWebView { if (!_webView) { [self setWebView: [UIWebView new]]; _webView.delegate = self; [self addSubview:_webView]; } } - (instancetype)init { self = [super init]; [self setUpWebView]; return self; } - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self setUpWebView]; } return self; } - (id)initWithCoder:(NSCoder *)aDecoder { if ((self = [super initWithCoder:aDecoder])) { [self setUpWebView]; } return self; } - (void) layoutSubviews { [super layoutSubviews]; CGRect frame = self.frame; self.webView.frame = frame; } #pragma mark - External methods. - (void) setHtmlInjection:(NSString *)html { [_webView loadHTMLString:html baseURL:nil]; } #pragma mark - Non-React component methods. - (void) fetchData { [MyExternalComponent getData:^(NSString *dataA, NSError *error){ if(error) { NSLog(@"Here be errors: %@", error); _onEventB(@{@"myError": error.localizedDescription}); } else { _onEventA(@{@"myData": dataA}); } }] } @end
React Native JavaScript Code:
// MyCustomView.js import React from 'react'; import { requireNativeComponent } from 'react-native'; class MyCustomView extends React.Component { constructor(props) { super(props); this._onEventA= this._onEventA.bind(this); this._onEventB= this._onEventB.bind(this); } _onEventA(event: Event) { if (!this.props.onEventA) { return; } this.props.onEventA(event.nativeEvent.myData); } _onEventB(event: Event) { if (!this.props.onEventA) { return; } this.props._onEventB(event.nativeEvent.myError); } render() { return ( <CustomView {...this.props} onEventA={this._onEventA} onEventB={this._onEventB} /> ); } } MyCustomView.propTypes = { htmlInjection: React.PropTypes.string, onEventA: React.PropTypes.func, onEventB: React.PropTypes.func, }; var CustomView = requireNativeComponent('CustomView', MyCustomView); module.exports = MyCustomView; // CustomWrapperContainer.js class CustomWrapperContainer extends React.Component { api: Object; constructor (props: Object) { super(props); this.state = { htmlInjection: '', myDataA: 'Some placeholder text' }; this.api = RestApi.create(); } render () { return ( <View style={styles.container}> <KeyboardAvoidingView behavior='position'> <Text>{this.state.myDataA}</Text> <MyCustomView style={styles.myStyle} htmlInjection={this.state.htmlInjection} onEventA={this.handleEventA.bind(this)} onEventB={this.handleEventB.bind(this)} /> </KeyboardAvoidingView> </View> ) } handleEventA = (data) => { console.log('on Event A', data); this.setState({myDataA: data}) }; handleEventB = (error) => { console.log('On Event B', error); }; } const mapStateToProps = (state) => { return { } } const mapDispatchToProps = (dispatch) => { return { } } export default connect(mapStateToProps, mapDispatchToProps)(CustomWrapperContainer)
I followed from React Native , as well as several others, but so far I have not been fortunate enough to receive the event to transition from iOS to React Native . I also could not find significant help in this matter from existing articles.
Ignite uses react version 15.3.2 . Perhaps this question? Or is there a version of some other dependency there? I'm not sure. I would really appreciate any help or leads.
PS: I ran this on both devices and simulators with iOS 9.2 through 10.0 , and I see no change in behavior, so this is not a problem.