前端收藏

原生组件传递属性到React Native(Android)

2017-02-10  本文已影响1958人  lyzaijs

从原生组件传递属性到React Native Ios 此文章中针对ios可以方便进行数据传递,但是没有与Android相关优雅实现方法

在React Native源码 ReactRootView中,有这样一个startReactApplication方法,它的第三个参数说明为:

{@param launchOptions} can be used to pass initial properties for the react component.

即可以在Android原生代码中通过传入bundle的方式,传入到JS代码中,在JS中 通过 this.props.xxx (xxx是在bundle中的key)取得。

以下是ReactRootView#startReactApplication的代码:

  /**
   * Schedule rendering of the react component rendered by the JS application from the given JS
   * module (@{param moduleName}) using provided {@param reactInstanceManager} to attach to the
   * JS context of that manager. Extra parameter {@param launchOptions} can be used to pass initial
   * properties for the react component.
   */
  public void startReactApplication(
      ReactInstanceManager reactInstanceManager,
      String moduleName,
      @Nullable Bundle launchOptions) {
    UiThreadUtil.assertOnUiThread();

    // TODO(6788889): Use POJO instead of bundle here, apparently we can't just use WritableMap
    // here as it may be deallocated in native after passing via JNI bridge, but we want to reuse
    // it in the case of re-creating the catalyst instance
    Assertions.assertCondition(
        mReactInstanceManager == null,
        "This root view has already been attached to a catalyst instance manager");

    mReactInstanceManager = reactInstanceManager;
    mJSModuleName = moduleName;
    mLaunchOptions = launchOptions;

    if (!mReactInstanceManager.hasStartedCreatingInitialContext()) {
      mReactInstanceManager.createReactContextInBackground();
    }

    // We need to wait for the initial onMeasure, if this view has not yet been measured, we set which
    // will make this view startReactApplication itself to instance manager once onMeasure is called.
    if (mWasMeasured) {
      attachToReactInstanceManager();
    }
  }

ReactActivityDelegateWrap

public class ReactActivityDelegateWrap extends ReactActivityDelegate {
    private Bundle mProps;
    public ReactActivityDelegateWrap(Activity activity, @Nullable String mainComponentName) {
        super(activity, mainComponentName);
    }

    public ReactActivityDelegateWrap(FragmentActivity fragmentActivity, @Nullable String mainComponentName) {
        super(fragmentActivity, mainComponentName);
    }

    @Nullable @Override protected Bundle getLaunchOptions() {
        return mProps;
    }

//设置传入props
    protected void setLaunchOptions(Bundle props) {
        mProps = props;
    }
}

交互界面,RNActivity(需要重写)

@Override protected ReactActivityDelegate createReactActivityDelegate() {
        Bundle bundle = new Bundle();
        bundle.putString("KEY", "login");

//替换ReactActivityDelegate 为 ReactActivityDelegateWrap
        ReactActivityDelegateWrap
                reactActivityDelegate = new ReactActivityDelegateWrap(this, getMainComponentName());
//传入props
        reactActivityDelegate.setLaunchOptions(bundle);
        return reactActivityDelegate;
    }

在js代码

//此 KEY 为原生中生成的(取得原生中传入的props)
        var key = this.props.KEY;
        ToastAndroid.show(key, ToastAndroid.SHORT);
上一篇下一篇

猜你喜欢

热点阅读