Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React native Required Unknown Module for custom native component

I am trying to implement custom native component for ReactNative. As per documentation i created all my components like below. But still i am getting error Required Unknown Module "MyCustomToast". Please help me to resolve this.

SampleToast.java:-

public class SampleToast extends ReactContextBaseJavaModule {


public SampleToast(ReactApplicationContext reactContext) {
    super(reactContext);
}

@Override
public String getName() {
    return "MyCustomToast";
}

@ReactMethod
public void showToast(String message) {
    Toast.makeText(getReactApplicationContext(), message, Toast.LENGTH_LONG).show();
}

}

MakeReactPackage.java:-

public class MakeReactPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {

    List<NativeModule> modules = new ArrayList<>();
    modules.add(new SampleToast(reactContext));
    return modules;

}

@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
    return Collections.emptyList();
}

@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
    return Arrays.asList();
}

}

MainActivity.java:-

public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler {

private ReactInstanceManager mReactInstanceManager;
private ReactRootView mReactRootView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mReactRootView = new ReactRootView(this);

    mReactInstanceManager = ReactInstanceManager.builder()
            .setApplication(getApplication())
            .setBundleAssetName("index.android.bundle")
            .setJSMainModuleName("index.android")
            .addPackage(new MainReactPackage())
            .addPackage(new MakeReactPackage())
            .setUseDeveloperSupport(BuildConfig.DEBUG)
            .setInitialLifecycleState(LifecycleState.RESUMED)
            .build();

    mReactRootView.startReactApplication(mReactInstanceManager, "HelloWorldBha", null);

    setContentView(mReactRootView);
}

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
        mReactInstanceManager.showDevOptionsDialog();
        return true;
    }
    return super.onKeyUp(keyCode, event);
}

@Override
public void onBackPressed() {
    if (mReactInstanceManager != null) {
        mReactInstanceManager.onBackPressed();
    } else {
        super.onBackPressed();
    }
}

@Override
public void invokeDefaultOnBackPressed() {
    super.onBackPressed();
}

@Override
protected void onPause() {
    super.onPause();

    if (mReactInstanceManager != null) {
        mReactInstanceManager.onPause();
    }
}

@Override
protected void onResume() {
    super.onResume();

    if (mReactInstanceManager != null) {
        mReactInstanceManager.onResume(this);
    }
}}

And in JS

react-native.js:-

MyCustomToast:require('MyCustomToast'),

SampleToast.js:-

 'use strict';

/**
 * This exposes the native ToastAndroid module as a JS module. This has a function 'show'
 * which takes the following parameters:
 *
 * 1. String message: A string with the text to toast
 * 2. int duration: The duration of the toast. May be ToastAndroid.SHORT or ToastAndroid.LONG
 */
var { NativeModules } = require('react-native');
module.exports = NativeModules.MyCustomToast;

Index.android.js:-

    /**
 * Sample React Native App
 * https://github.com/facebook/react-native
 */
'use strict';

var React = require('react-native');
var toastMessage = require('SampleToast')
var {
    AppRegistry,
    StyleSheet,
    Text,
    View,
    NativeModules
    } = React;




var HelloWorldBha = React.createClass({
    render: function () {
        return (
            <View style={styles.container}>
                <Text style={styles.welcome}>
                    Welcome to React Native!
                </Text>
                <Text style={styles.instructions}>
                    To get started, edit index.android.js
                </Text>
                <Text style={styles.instructions}>
                    Shake or press menu button for dev menu
                </Text>


                toastMessage.show('Bharath Kumar');

            </View>
        );
    }
});

var styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
    },
    welcome: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
    },
    instructions: {
        textAlign: 'center',
        color: '#333333',
        marginBottom: 5,
    },
});

AppRegistry.registerComponent('HelloWorldBha', () => HelloWorldBha);
like image 552
Santhi Bharath Avatar asked Oct 15 '15 10:10

Santhi Bharath


1 Answers

In SampleToast.js use the providesModule annotation. So SampleToast.js becomes:

/**
 * @providesModule SampleToast
 */

 'use strict';

 /**
  * This exposes the native ToastAndroid module as a JS module. This has a function 'show'
  * which takes the following parameters:
  *
  * 1. String message: A string with the text to toast
  * 2. int duration: The duration of the toast. May be ToastAndroid.SHORT or ToastAndroid.LONG
  */
 var { NativeModules } = require('react-native');
 module.exports = NativeModules.MyCustomToast;

Alternatively, when you use require('SampleToast') in Index.android.js then you would need to give the relative path. So if SampleToast.js and Index.android.js live in the same directory you would need

var toastMessage = require('./SampleToast');

Personally, I prefer the first option.

like image 181
The Observer Avatar answered Oct 15 '22 04:10

The Observer