Best practice to integrate existing app with React-Native #995

Closed
ssssssssssss opened this Issue Apr 24, 2015 · 4 comments

Comments

Projects
None yet
2 participants
@ssssssssssss

Hi There,

Thanks for your great work.
We have a bunch of legacy native code and want to have react-native get involved in the next version. As RN is not so feature complete to us, we'd like to experiment it as a component. Here are some thoughts about the future architecture based on our limited knowledge of RN, please comment.

  1. We'd like to create a minimal component in JS land and use it as RCTRootView at App start.
  2. As the App is native and RN hybrid, we'd like to reuse the *bridge created at first step, so it won't load JS files again.
  3. registerComponent for different kind of views in JS land, so we can have multiple entries for native code which manage the lifecycle of RN's RootView(s).
  4. Passing data back and forth between native code and RN. We experimented DeviceEventEmitter, but RN code runs in async mode, how can we guarantee the events send by native code will be listened in JS land? And we also tried AppParams.initialProps, but don't know how to get the value in JS land?

Thanks.

@nicklockwood

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood Apr 24, 2015

Contributor
  1. This should be fine. You can place one or more RCTRootViews anywhere in your app - they don't have to be the root view of the app, if that makes sense.
  2. That's also fine. Just create the bridge and store it somewhere (probably in a property in your app delegate). You can then re-use that bridge for each RCTRootView without re-creating or reloading it.
  3. I'm not sure what this means.
  4. You can pass properties in the -(NSDictionary *)exportedConstants method of each of your modules that will be available to the JS code immediately when it loads. For data that changes while the JS is running, you'll need to use the event emitters. These events are guaranteed to be received as long as the JS code is running and has registered to observe the event.
Contributor

nicklockwood commented Apr 24, 2015

  1. This should be fine. You can place one or more RCTRootViews anywhere in your app - they don't have to be the root view of the app, if that makes sense.
  2. That's also fine. Just create the bridge and store it somewhere (probably in a property in your app delegate). You can then re-use that bridge for each RCTRootView without re-creating or reloading it.
  3. I'm not sure what this means.
  4. You can pass properties in the -(NSDictionary *)exportedConstants method of each of your modules that will be available to the JS code immediately when it loads. For data that changes while the JS is running, you'll need to use the event emitters. These events are guaranteed to be received as long as the JS code is running and has registered to observe the event.
@ssssssssssss

This comment has been minimized.

Show comment
Hide comment
@ssssssssssss

ssssssssssss Apr 25, 2015

@nicklockwood Thanks for your reply, if addresses my concerns.

  1. Let me re-phase my questions. As we multiple RCTRootViews for different parts of the UI, so we'd like to make each RCTRootView backed by a JS component via "registerComponent". According to your previous answer, I think it's also feasible to do that.
  2. Any more documents about this?

@nicklockwood Thanks for your reply, if addresses my concerns.

  1. Let me re-phase my questions. As we multiple RCTRootViews for different parts of the UI, so we'd like to make each RCTRootView backed by a JS component via "registerComponent". According to your previous answer, I think it's also feasible to do that.
  2. Any more documents about this?
@nicklockwood

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood Apr 27, 2015

Contributor
  1. Yes, I think that's fine.

  2. Create your bridge like this:

    RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:URL_YOU_NORMALLY_PASS_TO_ROOTVIEW moduleProvider:nil launchOptions:nil];

Then store it somewhere in your app, e.g. in a property inside AppDelegate. Then whenever you create a new RCTRootView, do it like this:

RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:BRIDGE_YOU_CREATED_EARLIER moduleName:MODULE_NAME_FOR_THAT_COMPONENT];

That way, all of your root views will share the same bridge and javascript code, but can each run a different component.

Contributor

nicklockwood commented Apr 27, 2015

  1. Yes, I think that's fine.

  2. Create your bridge like this:

    RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:URL_YOU_NORMALLY_PASS_TO_ROOTVIEW moduleProvider:nil launchOptions:nil];

Then store it somewhere in your app, e.g. in a property inside AppDelegate. Then whenever you create a new RCTRootView, do it like this:

RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:BRIDGE_YOU_CREATED_EARLIER moduleName:MODULE_NAME_FOR_THAT_COMPONENT];

That way, all of your root views will share the same bridge and javascript code, but can each run a different component.

@ssssssssssss

This comment has been minimized.

Show comment
Hide comment

Thank a lot, @nicklockwood

@facebook facebook locked as resolved and limited conversation to collaborators May 29, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.