title: Native module in React Native: function returns "undefined"
body: <p>So, I am practicing making native modules in Java that can have functions exposed to the JavaScript code of React Native. For that, I decided to go for a simple demo math library. My code is as follows.</p>
  <p><code>MathOpsModule.java</code></p>
  <pre class="lang-java prettyprint-override"><code>package com.mb_rn_poc;
  
  import com.facebook.react.bridge.ReactContextBaseJavaModule;
  import com.facebook.react.bridge.ReactMethod;
  
  public class MathOpsModule extends ReactContextBaseJavaModule {
  
    @Override
    public String getName() {
      return &quot;MathOps&quot;; // Name of the Native Modules.
    }
  
    @ReactMethod
    public int add(int a, int b) {
      return (a + b);
    }
  }
  </code></pre>
  <p><code>MathOpsPackage.java</code></p>
  <pre class="lang-java prettyprint-override"><code>package com.mb_rn_poc;
  
  import com.facebook.react.ReactPackage;
  import com.facebook.react.bridge.NativeModule;
  import com.facebook.react.bridge.ReactApplicationContext;
  import com.facebook.react.uimanager.ViewManager;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.List;
  
  public class MathOpsPackage implements ReactPackage {
  
  @Override
  public List&lt;ViewManager&gt; createViewManagers(
    ReactApplicationContext reactContext
  ) {
      return Collections.emptyList();
  }
  
  @Override
  public List&lt;NativeModule&gt; createNativeModules(
        ReactApplicationContext reactContext
  ) {
      List&lt;NativeModule&gt; modules = new ArrayList&lt;&gt;();
      // Register the MathOps module
      modules.add(new MathOpsModule());
      return modules;
    }
  }
  </code></pre>
  <p><code>MainApplication.java</code></p>
  <pre class="lang-java prettyprint-override"><code>package com.mb_rn_poc;
  
  import android.app.Application;
  import android.content.Context;
  import com.facebook.react.PackageList;
  import com.facebook.react.ReactApplication;
  import com.facebook.react.ReactInstanceManager;
  import com.facebook.react.ReactNativeHost;
  import com.facebook.react.ReactPackage;
  import com.facebook.soloader.SoLoader;
  import java.lang.reflect.InvocationTargetException;
  import java.util.List;
  
  public class MainApplication extends Application implements ReactApplication {
  
    private final ReactNativeHost mReactNativeHost =
        new ReactNativeHost(this) {
          @Override
          public boolean getUseDeveloperSupport() {
            return BuildConfig.DEBUG;
          }
  
          @Override
          protected List&lt;ReactPackage&gt; getPackages() {
            @SuppressWarnings(&quot;UnnecessaryLocalVariable&quot;)
            List&lt;ReactPackage&gt; packages = new PackageList(this).getPackages();
            // Packages that cannot be autolinked yet can be added manually here, for example:
            // packages.add(new MyReactNativePackage());
            packages.add(new MathOpsPackage());
            return packages;
          }
  
          @Override
          protected String getJSMainModuleName() {
            return &quot;index&quot;;
          }
        };
  
    @Override
    public ReactNativeHost getReactNativeHost() {
      return mReactNativeHost;
    }
  
    @Override
    public void onCreate() {
      super.onCreate();
      SoLoader.init(this, /* native exopackage */ false);
      initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
    }
  
    /**
     * Loads Flipper in React Native templates. Call this in the onCreate method with something like
     * initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
     *
     * @param context
     * @param reactInstanceManager
     */
    private static void initializeFlipper(
        Context context, ReactInstanceManager reactInstanceManager) {
      if (BuildConfig.DEBUG) {
        try {
          /*
           We use reflection here to pick up the class that initializes Flipper,
          since Flipper library is not available in release mode
          */
          Class&lt;?&gt; aClass = Class.forName(&quot;com.mb_rn_poc.ReactNativeFlipper&quot;);
          aClass
              .getMethod(&quot;initializeFlipper&quot;, Context.class, ReactInstanceManager.class)
              .invoke(null, context, reactInstanceManager);
        } catch (ClassNotFoundException e) {
          e.printStackTrace();
        } catch (NoSuchMethodException e) {
          e.printStackTrace();
        } catch (IllegalAccessException e) {
          e.printStackTrace();
        } catch (InvocationTargetException e) {
          e.printStackTrace();
        }
      }
    }
  }
  </code></pre>
  <p>Now, on the React Native side of things, I have these two files -</p>
  <p><code>MathOps.js</code></p>
  <pre class="lang-js prettyprint-override"><code>import { NativeModules } from 'react-native';
  
  const MathOps = NativeModules.MathOps;
  
  export const add = (a, b) =&gt; {
      return MathOps.add(a, b);
  }
  </code></pre>
  <p><code>MainApp.js</code></p>
  <pre class="lang-js prettyprint-override"><code>import React, { useEffect, useState } from 'react';
  import { SafeAreaView, Text, View } from 'react-native';
  import { add } from &quot;./NativeWrapper/MathOps&quot;;
  
  const MainApp = () =&gt; {
  
      const [state, setState] = useState(0);
  
      useEffect(() =&gt; {
          let sum = add(10, 12);
          console.log({ sum });
          setState(sum);
  
      }, [])
  
      return (
          &lt;SafeAreaView&gt;
              &lt;View&gt;
                  &lt;Text&gt;
                      {state}
                  &lt;/Text&gt;
              &lt;/View&gt;
          &lt;/SafeAreaView&gt;
      );
  }
  
  export default MainApp;
  </code></pre>
  <p>The problem is, the <code>add</code> function is returning <code>undefined</code>. As such, nothing gets printed on the screen. Any idea what I might be doing wrong?</p>