RN 如何给页面传参数

2020-10-24  本文已影响0人  莫帆海氵

基于 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
})
props.navigation.state.params

props.navigation.getParam('abc')

和 native 混合开发时,从 native 打开 RN 页面传递参数

通过下面三步获取

// 示例调用的代码,不完整

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;
        }

}

不直接使用 navigation 创建的对象,用普通的组件包裹一层,追加 screenProps 属性


const AppNavigator = createStackNavigator(
  {
    Root: {
      screen: RootPage,
    },
  },
)

const App = (props) => {
  <AppNavigator screenProps={props} />
}

AppRegistry.registryComponent('app', () => App)


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 到页面

上一篇 下一篇

猜你喜欢

热点阅读