Wednesday, June 29, 2016

Beware of Navigator

One of the first things you probably set up in your RN app is Navigator. Unlike NavigatorIOS, this works in both iOS and Android. However, the animation for Navigator is done in the JS thread which creates two serious problems.

First problem: Animation is very slow in the app.


Facebook acknowledges this problem, but the solution they offer isn't good (follow the link and take a read). Apart from the fact that having a renderPlaceholderOnly variable in state is messy, it only works when you push to the Navigator, not when you pop.

Second problem: Animation is even slower when you run in 'Debug in Chrome'.

In fact, it runs so slowly that I thought I'd frozen the app. If you're patient enough you can see the animation starting, but I've never waited for it to complete. When I'm developing with this option, I just replace any push onto the Navigator with replace. It breaks some functionality (you can't go back by popping) but at least you can run your code and debug it.




Adding packages if your MainActivity extends ReactActivity

I was recently trying to get some audio to play in my App. I was trying to use react-native-audioplayer because it works in both Android and iOS. The instructions include the following:

public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler {
  ...

  @Override
  protected void onCreate(Bundle savedInstanceState){
    ...
    mReactInstanceManager = ReactInstanceManager.builder()
      .setApplication(getApplicatio)
      ...
      .addPackage(new MainReactPackage())
      .addPackage(new RNAudioPlayer())   //  <--- add here 
      ...
  }
}

So pretty simple - just add the RNAudioPlayer package to the ReactInstanceManager builder and we're good to go, right?

Except that my MainActivity doesn't contain an onCreate method or any of the code in it. I originally thought I just needed to create this method and add code to it, until I realised that the example was extending from Activity and my class was extending from ReactActivity.

The builder already exists in ReactActivity, and to add a package you just need to add it to the getPackages method, like so:

@Override
protected List<ReactPackage> getPackages() {
    return Arrays.<ReactPackage>asList(
        new MainReactPackage(),
        new RNAudioPlayer()
    );

}