Tôi có chế độ xem gốc tùy chỉnh trong một dự án Ignite
. Tôi đang cố gắng thiết lập một liên lạc từ Objective-C
đến React Native
. Giao tiếp từ React Native
đến iOS
hoạt động với tiêm HTML
, nhưng không phải là cách khác. Tôi đã thử sử dụng cả hai RCTBubblingEventBlock
và RCTDirectEventBlock
, nhưng không hoạt động. Đây là toàn bộ việc triển khai của tôi. Tôi đã thay đổi tên của các thành phần của khóa học, và chỉ còn lại thực hiện rất cần thiết cho sự hiểu biết của bạn về những gì đã được thực hiện cho đến nay:Các thành phần UI gốc phản ứng: RCTBubblingEventBlock/RCTDirectEventBlock dường như không hoạt động
Objective-C
mã:
// 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
mã:
// 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)
Tôi đã theo dõi example từ chính bản thân số React Native
và một số thứ khác, nhưng tôi đã không có may mắn cho đến nay khi nhận được sự kiện để vượt qua từ iOS
đến React Native
. Tôi đã không thể tìm thấy sự trợ giúp đáng kể trong vấn đề này từ các bài viết hiện có.
Ignite
sử dụng react
phiên bản 15.3.2
. Có lẽ đó là vấn đề? Hoặc phiên bản của một số phụ thuộc khác ở đó? Tôi không chắc. Tôi rất cảm kích sự giúp đỡ hay dẫn dắt.
P .: Tôi đã chạy nó trên cả hai thiết bị và mô phỏng chạy iOS 9.2
thông qua 10.0
và tôi không thấy bất kỳ thay đổi nào về hành vi, vì vậy đó không phải là vấn đề.
điều đầu tiên tôi nghĩ đến khi nhìn thấy điều này, là hãy chắc chắn để xem xét thử v2 cầu RNWebview. Việc này sẽ sớm được đưa vào RN Master: https://github.com/alinz/react-native-webview-bridge/tree/v2 – GantMan
Cảm ơn bạn. Nhưng tôi không hiểu làm thế nào điều này liên quan đến vấn đề tôi đang gặp phải. Tôi có một webView mà tôi tải nội dung HTML và nó hoạt động tốt. Chỉ khi tôi cố gắng trả lại dữ liệu qua các cuộc gọi lại thì giao tiếp không hoạt động. –
Vâng, xin lỗi tôi đã không thấy bất cứ điều gì sai với mã này vì vậy tôi đã hy vọng sẽ cung cấp một số thông tin bổ sung. Bạn có mã này trong một repo tôi có thể truy cập? – GantMan