基于 react-native@0.59.9 + react-navigation@2.18.2
在 RN 内部如何给页面传参
有两种方式一种默认参数、一种跳转动态追加的参数
- 给页面设置一个默认参数
const MainStack = createStackNavigator(
{
Root: RootPage,
},
{
initialRouteParams: {
abc: 193
},
}
)
- 在应用内通过路由跳转带上参数
props.navigation.navigate('Test', {
abc: 193
})
- 在页面中通过 navigation 对象可以获取传递的参数
props.navigation.state.params
props.navigation.getParam('abc')
和 native 混合开发时,从 native 打开 RN 页面传递参数
通过下面三步获取
-
native 中追加 initialProps,传入 initialProps
- iOS
// 示例调用的代码,不完整
NSDictionary *initalProps = @{@"abc":193};
NSURL *jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.bundle?platform=ios"];
NSString *moduleId = @"mt-rn-dev";
[[ReactController alloc] initWithModule:jsCodeLocation moduleId:moduleId initalProps: initalProps];
// 通过 RCTRootView 打开 RN
#import <Foundation/Foundation.h>
#import "ReactController.h"
#import <React/RCTRootView.h>
@interface ReactController()
@property (nonatomic, strong) NSString *moduleId;
@property (nonatomic, strong) NSDictionary *initalProps;
@property (nonatomic, strong) NSURL *bundleURL;
@end
@implementation ReactController
- (instancetype)initWithModule:(NSURL *) bundleURL moduleId:(NSString *)moduleId initalProps:(NSDictionary *) inital{
if (self = [super init]) {
self.bundleURL = bundleURL;
self.moduleId = moduleId;
self.initalProps = inital;
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self initView];
}
-(void)initView {
NSLog(@"bundle %@ %@",self.bundleURL, self.moduleId);
RCTRootView *view =[[RCTRootView alloc] initWithBundleURL: self.bundleURL moduleName: self.moduleId initialProperties:self.initalProps
launchOptions: nil];
view.frame = self.view.bounds;
view.backgroundColor = [UIColor whiteColor];
[self setView:view];
}
@end
- android
// 示例代码,不完整
Intent intent = new Intent(this, RNDevActivity.class);
startActivity(intent);
// 继承 ReactActivity
package com.mt.xxx;
import android.os.Bundle;
import android.support.annotation.Nullable;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
public class RNDevActivity extends ReactActivity {
@Override
protected String getMainComponentName() {
return "mt-rn-dev";
}
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new MyreactDelegate(this, getMainComponentName());
}
class MyReactDelegate extends ReactActivityDelegate {
public MyReactDelegate(Activity activity, @Nullable String mainComponentName) {
super(activity, mainComponentName);
}
@Nullable
@Override
protected Bundle getLaunchOptions() {
Bundle bundle = new Bundle();
bundle.putString("abc", 193);
return bundle;
}
}
- RN 启动入口中增加 screenProps,
不直接使用 navigation 创建的对象,用普通的组件包裹一层,追加 screenProps 属性
const AppNavigator = createStackNavigator(
{
Root: {
screen: RootPage,
},
},
)
const App = (props) => {
<AppNavigator screenProps={props} />
}
AppRegistry.registryComponent('app', () => App)
- RN 页面中通过 props.navigation.getScreenProps() 获取
const RootPage = props => {
console.log(props.screenProps);
console.log(props.navigation.getScreenProps());
return (
<View />
);
};
有遇到在重写 registryComponent 后,组件里接受不到 native 中传过来的 initialProps
在 toast 组件中为了方便绑定 view 到页面中,通过重写 registryComponent 方法,默认追加 toast 的 view,但这样造成 native 传入的 initialProps 无法在 RN 页面里正确通过 props 获取
const originRegister = AppRegistry.registerComponent
AppRegistry.registerComponent = (appKey, component) => originRegister(appKey, () => {
const OriginAppComponent = component()
return () => (
<View style={styles.container}>
<OriginAppComponent />
<RootView />
</View>
)
})
最后还是移除这个重写方法,通过别的方式绑定 view 到页面
网友评论