Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the correct way to develop components for Android and iOS?

Tags:

react-native

At our company we have several React Native components built for iOS. They are all JavaScript based components, so they should work under React Native for Android also. Also, most of the components we have should only differ in the design style, so we need to code those differences between both platforms.

What's the right way to enable this components to support Android? Do we have to use if's checking the app Platform and change the style accordingly? If we want to separate the components in two files, Component.android.js and Component.ios.js, is React Native going to automatically detect which one it needs to use depending on the platform it's running?

like image 328
amb Avatar asked Jan 08 '23 09:01

amb


2 Answers

There is a very simple solution which I prefer. Just use the file extension: .ios. vs .android.

enter image description here

E.g. look at my nav. I use the android toolbar in the android nav and then I can use navigatorIos for ios if I wish. The application platform will correctly load the corresponding platform file just based on the extension. Which means I just load it normally:

var Nav = require('./jsx/Nav');

I like to follow a declarative approach that React talks about, thus:

1) organizing your files would be by function/behaviour and not by platform as the same file with different extensions will be next to each other.

2) Whether platform to be explicit or implicit isn't relevant as you will only split the file into extensions when it's different platform specific components (so this is inherent)

3) Never any need to handle different platform(s) behaviour in your code ever.

4) This is a composition solution as I've already mentioned: files that are cross-platform do not need the platform extension (and might not need an abstract class for extension in some cases even).

This is a simple solution and I do not know how well it would scale for large projects; but I'm all for the declarative simplicity about it.

like image 51
Tjorriemorrie Avatar answered Jan 16 '23 20:01

Tjorriemorrie


1. Organize them

  • Some components will be IOS-only, some will be Android-only, and some will be cross-platform.
  • I place my components into 3 directories:

    /common/components/ /android/components/ /ios/components/

2. Decide whether you want platform to be explicit or implicit

  • For every component, there are two basic approaches:
    1. Have the parent manage the platform via composition (i.e. parent selects which component to render and/or passes the platform into the children)
    2. Delegate the platform rendering to the child (i.e. child figures out what platform it's on and renders itself accordingly).
  • The right approach depends on how different your IOS vs Android layout, style, and functionality are. If the two platforms have different layouts and features, you will likely favor the composition approach. If your code is really isomorphic across platforms then you will likely favor delegation.

3. For trivial differences, use if or switch

  • If the differences between IOS and Android flavors are purely stylistic (e.g. different style sheet), then you can use a simple if to retrieve the right style.

4. For more significant differences, use inheritance and composition for better modularity

  • If you have a component which has significant differences between IOS and Android (e.g. <MyCameraWidget>), then you might use a base <BaseCameraWidget> and then have <CameraWidgetIOS> and <CameraWidgetAndroid> variants which extend the base component. This properly separates the cross-platform from the platform-specific logic for better component maintainability later on.
    • The variants may live in different files, or in the same file, depending on whether you want to expose them or not.
    • If you are using delegated platform rendering, you will likely want to create a <CameraWidget> facade which has the simple task of figuring out what plaform its on and rendering the correct <CameraWidgetIOS> or <CameraWidgetAndroid> component.

Finally, read this Facebook article on adjustments you may want to make with the React Native packager. There is a blacklist feature which allows you to block out android or IOS files for different builds, but as of today that feature is undocumented and potentially not yet released.

like image 43
tohster Avatar answered Jan 16 '23 20:01

tohster