React: Calling JS function after bridge has been destroyed --- How to find which function - react-native

I'm working on an update for our app. I've added a HeadlessTask and I've started seeing this warning in the console:
React: Calling JS function after bridge has been destroyed
How can I get the name of the function being executed?

From the error message I assume you're in java (react-native Android):
When you reload on react-native, what happens behind the scenes is that the react context is getting destroyed, and a new one is being created.
That error get's thrown whenever a react-native Native Module is trying to do work, by using the old react context (the one that was valid before the reload).
The last time I saw that error it also included an explanation as to which module tried to do work by using the old context. Typically it's the RCTDeviceEventEmitter module trying to send a message to javascript.
You'll have to open logcat on Android studio and read the full error message.
p.s: If you're using react-native-navigation in your project, (after you discover which module is the trouble maker by using the logcat), make sure to search on their issues as they are heavily using the native side of react-native android, and I've seen lot's of similar issues so far.

Never found a good solution to this until recently, so thought I'd put this here in case it helps someone else. I finally got around this error by doing the following:
public class RNMyNativeModule extends ReactContextBaseModule {
private ReactApplicationContext currentContext;
public RNMyNativeModule(ReactApplicationContext reactContext) {
super(reactContext);
currentContext = reactContext;
}
public void myEmitFn(String emitMe) {
currentContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("RNMyNativeModuleEvent", emitMe);
}
}
Basically, in your module constructor, make sure you capture the currentContext in it's own variable, and just use that whenever you need it. Otherwise it gets overwritten and destroyed whenever a live reload happens, and getReactApplicationContext() is not actually giving you the current context.

Related

React Native App Working in Development, 'Error: 'undefined' is not a function' in Production

I have completed an app that builds on both Android and iOS. It works as expected when I build the app from the CLI or when I build it via XCode / Android Studio. However, on TestFlight, it gets errors that simply do NOT exist when I build it locally. These errors only appear on TestFlight, and thus I have little to no idea on how to go finding them down or even resolving them. Does anyone have better expertise in this area?
I'm not sure how common an issue this is-- I've never heard of it before to be honest, but the components that were not working were components that utilized ({props}) in a component. For example, any component wthat utilized the following declarations did NOT work
function Example({props}){
// stuff
}
// OR //
const Example = ({props}) => {
// stuff
}
all of the values inside of props were unreadable. I fixed this by simply moving EVERYTHING into a recoil state instead and that mitigated any errors. For example...
navigation.navigate("path",{prop1: value})
// AND //
return (<Example prop={value} prop={value})
would not work unless the prop was a single value-- a string, an int, a bool, these would work. Objects and Arrays did NOT properly carry over.
Hope this helps someone in the future.

The keyPrefix reduxPersist: is already in use

Pressing Cmd + I on ios simulator, I receive an error :
"The keyPrefix reduxPersist: is already in use. Multiple clients cannot share the same keyPrefix. Provide a different keyPrefix in the offlineConfig object."
Im using appSyncClient and not using redux. Error refers to new AWSAppSyncClient
The problem was that when I create new AWSAppSyncClient, I have set "disableOffline" property to false, after I changed it, everything works as expected.
This issue occurs when multiple appsync clients are being created with same keyPrefix, lets say in a scenario while creating react app, if multiple rerenders are happening and client is created inside render function of class component, then client will be created multiple times and it will thow this error. Moving creating appsync client outside the react component solved this error for me.

Persistent React-Native error that goes away with Remote Debugging enabled

I'm building a React-Native app and whenever I run it on my Android emulator, I get this error:
Objects are not valid as a React child (found: object with keys
{$$typeof, type, key, ref, props, _owner, _store}). If you meant to
render a collection of children, use an array instead.
throwOnInvalidObjectType
D:\rn\manager\node_modules\react-native\Libraries\Renderer\ReactNativeRenderer-dev.js:7436:6
Because this error means nothing to me, I decide to enable "Debug JS Remotely" in Chrome to see if I can get an error I understand. But with Debug Remotely enabled, the error goes away.
If I build the project and install the app on a real device, the errors come back.
But I feel like I'm stuck in a catch-22 because if I try to debug, I get no errors, and if I turn off debugging, I get errors.
Is there anyway to get around this?
Thanks!
The error mentions you use an object in your render() method where you shouldn't. Since you did not post any code, here is what you could do:
Keep removing elements from your render() method until you no longer get the error. Once it is gone, start placing code back until you hit the error again. The code causing the error will be or return an object, possibly a typo causing an object to be returned instead of a string for instance.
TL;DR: Stopped using firebase and used react-native-firebase instead
The problem for me wasn't the render method in any of my components or classes. I realized after trying the answer above, I basically removed all my files, and was left with one file. I changed the render method to display text inside one view, but I still got the error.
Then I started removing the modules I was importing inside that file one by one and found that it was the firebase module uninstalled firebase and installed react-native-firebase.

Is there a oficial plugin or SDK to use MercadoPago in React-Native for iOS?

The problem here is that I need call MercadoPago in mi Application using React-Native, but i can not find the way,
I found this wrapper for use in React-Native,
https://github.com/shovelapps/react-native-mercadopago
but when I am trying to call it I have an error in startCheckOut method,
I am using in this way the Wrapper
import RNMercadopago from 'react-native-mercadopago';
and I am calling the method in a click event using this line:
RNMercadopago.startCheckout(publicKey, prefId, null, false, (payment) => { this._success(payment)}, (error) => { this._failure(error) });
but I am getting the bellow error,
undefined is not an object (evaluating 'RNMercadopago.startCheckout)
all this code is in the index.ios.js
best regards
you may use react-native-mercadopago-checkout. It allows you to implement MercadoPago checkout in two diferent ways (both of them are documented).
It's a new implementation that is working in a production app. Even, if you find a bug, you could open an Issue and be sure that it will be resolved!

Confusing Swift type annotations for React Native Promises

I'm playing around with React Native and attempting to write some native code that communicates over bluetooth. I'm confused by the type annotations that I need to use in order for it to work. Could someone please explain why I have to have the "resolver" and "rejecter" bits in the following two code snippets? Is there a way to write this without those unused parts?
My implementation, MyAsyncModule.swift:
#objc(MyAsyncModule)
class MyAsyncModule: NSObject {
#objc func echoAsync(
input: NSNumber,
resolver resolve: RCTPromiseResolveBlock,
rejecter reject: RCTPromiseRejectBlock
) -> Void {
resolve(input)
}
}
From my bridge file, MyAsyncModuleBridge.m
RCT_EXTERN_METHOD(echoAsync:
(nonnull NSNumber *)input
resolver:(RCTPromiseResolveBlock *)resolve
rejecter:(RCTPromiseRejectBlock *)reject
)
I am coming from scripting land so types are foreign to me, but it seems too weird that React Native refuses to identify my the echoAsync method unless both the implementation and the bridge include the resolver and rejecter bits...
The resolver and reject calls are needed to have the framework generate a "promise". A promise can be thought of as a placeholder for a value that will be made available in the future. The resolver is called when the native code is done doing its work and is ready to pass the results back to the JavaScript land. reject is used when the native side detects an error and is used to report that error from native to JavaScript land.
To get a bit deeper, when you're JavaScript calls a native function, it doesn't pause and wait for native to finish up like a normal function call. It instead just goes on executing the next line of code (notice how React-Native prevents you from setting a return value for your exported functions meaning they are explicitly making sure you don't try and wait for a return value).
So then how does native code ever report the results back to JavaScript? There are two options
callbacks (in native these have the type RCTResponseSenderBlock) when called, cause a JavaScript function to run with the passed arguments
promises (with the types RCTPromiseResolveBlock and RCTPromiseRejectBlock) which causes you success handler to run with the passed arguments when resolver is called or causes your error handler to run when reject is called.
As for async function you MUST use promises.
For more info on JavaScript promises checkout:
http://www.html5rocks.com/en/tutorials/es6/promises/
https://facebook.github.io/react-native/docs/native-modules-ios.html#promises