It turns out to be error when use:
import NativeMethodsMixin from 'NativeMethodsMixin';
import { requireNativeComponent } from 'react-native'
Is there any better way to access the private class( never export ) such as NativeMethodsMixin?
eg:
Thanks
Hmm, React Native doesn't export NativeMethodsMixin - does the RN packager allow you to import NativeMethodsMixin using Haste? And requireNativeComponent doesn't make sense for Web (you should probably avoid importing it in modules that need to run on web)
Yeah, RN packager supports haste ( with providesModule declare ). And I agree with you that the APIs don't make sense.
Actually, if we wanna build a web app with ReactNative Code, some of the APIs are very necessary to be translated in web. When we use this project, we must have already developed a RN app first, so I think we should translate them rather than avoiding importing these functions, How about you?
I'm going to close this because a) RN doesn't explicitly export NativeMethodsMixin, b) and requireNativeComponent doesn't make sense for web. If you were to import/use RNW's createDOMElement that would also throw an error. You should consider requireNativeComponent as an iOS/Android specific module and it should be avoided in any code that needs to run on web.
I think a custom webpack plugin that resolves requireNativeComponent is the best temporary solution, but I wasn't able to figure out how to do so. Instead I opted to create a very basic implementation inside of react-native-web so that I could use react-native-iterable on web, iOS, and Android. There's still a lot left to implement.
I have mixed feelings about requireNativeComponent being considered an iOS/Android specific module. While I agree with your argument @necolas, it'd still be very convenient to use libraries that don't currently target web.
@L1fescape , WRT " _it'd still be very convenient to use libraries that don't currently target web_". You were right...
I am running into the same issue with React-native-material kit, which I am struggling to keep for the web (as I used it extensively in my react-native app).
./node_modules/react-native-material-kit/lib/internal/MKTouchable.js:66
63 | onTouch: PropTypes.func,
64 | };
65 |
> 66 | const NativeTouchable = requireNativeComponent('MKTouchable', {
67 | name: 'MKTouchable',
68 | propTypes: MKTouchable.propTypes,
69 | }, {
Seems like I have rewrite my app to remove usage of RNMK (at least for the web).
@necolas
It's used in popular library react-native-svg and it's really not possible not use svg.
Any work around for by pass this error?
@hiteshagja I had same problem, I used babel module resolver and react-native-svg-web in my babel.config.js to overcome this.
`const isWeb = process.argv.reduce(
(f, e) => f || e.includes('web'),
false
);
module.exports = (api) => {
api.cache(true);
if (isWeb) {
return {
plugins: [
[
'module-resolver',
{ alias: { 'react-native-svg': react-native-svg-web } },
],
'@babel/plugin-transform-runtime',
'@babel/plugin-syntax-dynamic-import',
'@babel/plugin-transform-modules-commonjs',
'@babel/plugin-transform-react-jsx',
'@babel/plugin-proposal-optional-chaining',
'@babel/plugin-proposal-nullish-coalescing-operator',
['@babel/plugin-proposal-decorators', { legacy: true }],
['@babel/plugin-proposal-class-properties', { loose: true }],
'@babel/plugin-proposal-export-default-from',
'@babel/plugin-transform-flow-strip-types',
],
sourceType: 'unambiguous'
};
} else {
return {
presets: ['babel-preset-expo', { web: { transformImportExport: true } }],
}
}
};
`
I hope this will help you
Below can fix requireNativeComponent, and you can also modify it to fix NativeMethodsMixin too
npm install --save-dev react-app-rewired
Create a config-overrides.js in your project root
// used by react-app-rewired
const webpack = require('webpack');
const path = require('path');
module.exports = {
webpack: function (config, env) {
config.module.rules[1].use[0].options.baseConfig.extends = [
path.resolve('.eslintrc.js'),
];
const webAliases = {
'react-native': path.resolve('web/aliases/react-native'),
};
Object.assign(config.resolve.alias, webAliases);
config.plugins.push(
new webpack.DefinePlugin({
__DEV__: process.env.NODE_ENV !== 'production',
}),
);
return config;
},
paths: function (paths, env) {
paths.appIndexJs = path.resolve('index.web.js');
paths.appSrc = path.resolve('.');
paths.moduleFileExtensions.push('ios.js');
return paths;
},
};
Also create a web/aliases/react-native/index.js
// ref to https://levelup.gitconnected.com/react-native-typescript-and-react-native-web-an-arduous-but-rewarding-journey-8f46090ca56b
import {Text as RNText, Image as RNImage} from 'react-native-web';
// Let's export everything from react-native-web
export * from 'react-native-web';
// And let's stub out everything that's missing!
export const ViewPropTypes = {
style: () => {},
};
RNText.propTypes = {
style: () => {},
};
RNImage.propTypes = {
style: () => {},
source: () => {},
};
export const Text = RNText;
export const Image = RNImage;
// export const ToolbarAndroid = {};
export const requireNativeComponent = () => {};
Now you can just run react-app-rewired start instead of react-scripts start
Most helpful comment
I'm going to close this because a) RN doesn't explicitly export
NativeMethodsMixin, b) andrequireNativeComponentdoesn't make sense for web. If you were to import/use RNW'screateDOMElementthat would also throw an error. You should considerrequireNativeComponentas an iOS/Android specific module and it should be avoided in any code that needs to run on web.