React Native imports not working after upgrade - javascript

Hi I've been in charge of an old React-Native iOS project and I need to upgrade its React-Native from 0.25.1 to 0.48.0 but I'm running into a lot of compiler issues and can't figure out how to update the code.
I have an index.ios.js file that looks like this:
var ReactNative = require('react-native');
var ResumeIns = require('./resume_ins_controller');
ReactNative.AppRegistry.registerComponent('ResumeInsController', () => ResumeIns.Navigation);
A resume_ins_controller.js in the root folder that looks like this:
var React = require('react');
var EntryManager = require('./entry_manager.js');
class ResumeInsNavigation extends React.Component {
//....
}
and an entry_manager.js in the root folder that looks like this:
class EntryManager {
//....
}
module.exports = EntryManager;
This code worked OK before the upgrade, but now I get this error:
Super expression must either be null or a function, not undefined
and the stack trace points to this line:
module.exports = EntryManager;
Does anyone know how to get this code working for React-Native 0.48?

There's been a ton of changes since 0.25.1. Knowing how painful updates can get, I'd suggest either:
In case of a very complex app: to update RN version by version with the help of release notes, and rn-diff if necessary.
In case of a fairly simple app: to start a new RN project from scratch, and move the app's logic over there.
Either way it would be a good idea to move to ES2015 imports for clarity on named vs default imports as the issue that you're describing is likely caused by the way things are imported, see v0.25.1 deprecations + a link to codemod that may help.
Good luck!

Related

Using react component in a different application

What I'm trying to achieve is:
Building simple react app - the template is create react app
Copying output file (main.*.js)
Pasting it in another react app
Importing render function to render the first app into the second one
Simple react app code:
interface Props {
greeting: string;
}
export module AppModule {
export const sendGreetings = ({ greeting }: Props) => {
return `Hello ${greeting}`;
};
}
Builder file code:
!function(){"use strict";var n;(n||(n={})).sendGreetings=function(n){var e=n.greeting;return"Hello ".concat(e)}}();
Trying to import this file into another app I get this error:
File 'c:/vscode/test-react-app/test-sc-react/src/main.783e0281.js' is not a module.ts(2306)
Which is obvious. I changed the output file manually to:
export function initApp(){"use strict";var n;(n||(n={})).sendGreetings=function(n){var e=n.greeting;return"Hello ".concat(e)}};
It works but the only function that I'm able to access is initApp but not sendGreetings
I've been struggling with this for a while now and I would really appreciate any helpful suggestions
I used Bit.dev for my components that are used across multiple applications & there is an article regarding your issue
https://blog.bitsrc.io/sharing-react-components-across-multiple-applications-a407b5a15186
I think it would help.
🎯 Solution #1
You can use an iframe to inject your react app:
<iframe src='path-to-your-app.html'/>
🎯 Solution #2
Go with micro-frontend architecture approach. Where a front-end app is decomposed into individual, semi-independent "microapps" working loosely together.
As a starting point, you can try npx create-mf-app instead of the CRA.
You can include your js code directly on run time. You can use window.addEventListener to load js/css incoming from an outside source. You just have to append that js to your document on the load event.

When using React Native + Expo, where is the iOS API accessed?

I'm following the Expo tutorial where you build a simple image-sharing application (https://docs.expo.dev/tutorial/image-picker/).
I'm curious where in node_modules is the actual code that accesses the iOS permissions interface.
For example, in app.js I have the following code:
let permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync();
The requestMediaLibraryPermissionsAsync method is located in node_modules/expo-image-picker/build/ImagePicker.js where I find:
export async function requestMediaLibraryPermissionsAsync(writeOnly = false) {
const imagePickerMethod = ExponentImagePicker.requestMediaLibraryPermissionsAsync;
return imagePickerMethod(writeOnly);
}
Going to node_modules/expo-image-picker/build/ExponentImagePicker.js I find:
import { NativeModulesProxy } from 'expo-modules-core';
export default NativeModulesProxy.ExponentImagePicker;
//# sourceMappingURL=ExponentImagePicker.js.map
This is where I'm becoming confused, and I'm not sure how to continue tracing through the modules. I see in node_modules/expo-modules-core/ios/interfaces/Permissions there are objective-c files related to iOS permissions - are these being used in this code example? Where in the code are we actually accessing the iOS API? I have a strong feeling that I'm approaching this question from the wrong angle, so please excuse my ignorance.
I think you have to look at the repository https://github.com/expo/expo/search?q=ExponentImagePicker
Try to find the API names you need.

Building Flux/React application without NodeJs EventEmitter

Hi I'm trying to build a Flux/React application with a go-lang back-end. I have been following a tutorial I found here. But I have a problem when building the store. In the tutorial something like this is used to create a base for the store.
var ProductStore = _.extend({}, EventEmitter.prototype, {...});
The problem I have is I do not have access to the EventEmitter library which I understand is a Nodejs lib? Is there an alternative I can use?
You can use NodeJS libraries in the browser! Take a look at browserify.
First some code:
// index.js
var EventEmitter = require("events").EventEmitter;
var ProductStore = function() {};
ProductStore.prototype = new EventEmitter;
Then you run browserify on it:
browserify index.js > bundle.js
Also worth a look is WebPack which does the same thing. (but has some additional features)
Well if you are using the flux implementation given by Facebook (https://github.com/facebook/flux), you can actually extends their FluxStore class which comes with a build in eventEmitter.
The only thing if you want to do that is you must use es6 classes (and use babel to transpile to es5).
The good thing about it is that you don't have to implement the addListener removeListener and emitChange methods, and that's very DRY :)
With this solution, your stores will end up looking like that :
var FluxStore = require("flux/utils").Store,
thing;
class ThingStore extends FluxStore {
getThing() {
return thing;
}
__onDispatch(payload) {
//your code
}
}

Common js modules in react native

Is it possible to make use of common js modules with react-native? The use case is sharing logic between a mobile and web version of a react project.
Ok, I'm new to this too but I think I've figured out how to include js code. I didn't have to add anything to the standard react native installation.
Create a Library of code:
//library.js
exports.foo = function() {
//Do stuff here
return "Here";
}
Import into another js file:
var lib = require("./library.js");
var myString = lib.foo();
I found the info from this blog post:
http://0fps.net/2013/01/22/commonjs-why-and-how/

Unit testing on "react + react-route" stack

I've read many recommendations of how it's possible to render routed via react-router components, but I still can't to make it work. I tried to find it using github codebase search, still no luck. And at this point all I need is one working example.
Here is my boilerplate project, but maybe it's not important. I just want to see some react-route unit-testing working example.
I got mine working after I found the super-secret hidden react-router testing guide.
Instead of using Object.assign to create a router stub, I used sinon.js so I could create better stub functions that return the appropriate values for my tests.
EDIT: Went back to look again at your boilerplate and saw that your stub router is borrowed from the same example. Sorry. So where exactly did you get stuck?
EDIT-AGAIN: I'm not using Jest, so here are the other pieces that I needed to solve the testing puzzle:
If you're using browserify, and want to test in plain mocha (without having to build), you'll need to hack require to compile your jsx for you:
var fs = require("fs");
var reactTools = require("react-tools");
require.extensions[".jsx"] = function(module, filename) {
var jsxContent = fs.readFileSync(filename).toString();
var jsContent = reactTools.transform(jsxContent);
return module._compile(jsContent, filename);
};
You need a fake DOM. JSDOM is just plain terrible. I got it working using domino instead.
var domino = require("domino");
global.window = domino.createWindow();
global.document = global.window.document;
//Set the NODE_ENV so we can call `render`.
//Otherwise we get an error from react about server rendering. :(
process.env.NODE_ENV = "test";
Then you can require your components in through the stub-router, and render your components into DOM nodes using React.render():
var MyComponent = fakeRouter(require("./MyComponent.jsx"));
var component = React.render(
< MyComponent / > ,
document.body
);
node = component.getDOMNode();
//I used `zepto-node` and `chai-jq` to assert against my components
The (possbily new in v4) way of doing this is to wrap the component you're testing in the MemoryRouter provided by react-router.
import {MemoryRouter} from 'react-router-dom';
import {render} from 'react-dom';
render(<MemoryRouter>
<YourComponent>
</MemoryRouter>, node, () => {});

Categories