Multiple times now I’ve come to situations where React Native just hangs up, and stops execution of a promise or generator-based function in the middle, with no error message. Today I debugged one involving an
async function that calls out to native code.
- From within
useEffectI’m calling out to a native module that does decryption.
- When called from
useEffect,the function runs, and never completes. Its promise is never fulfilled.
- No error is thrown
- Steps past the first
awaitkeyword are not reached.
- If I move the function invocation to the top level of the file, outside of the React component definition, the function runs to completion successfully.
- Running the function in an
onClickhandler also does not complete.
- Actually it does? After the first reload of the JS bundle, the simulator did not complete the function after click. After subsequent reloads, it did complete the function on button click.
- Okay, now I try
useEffectagain, and the function does complete successfully.
- When called from
The workflow I’m using above is to comment in / comment out parts of code, go to the metro bundler in the terminal, and hit
r to refresh the simulator. Is there something funky in the refresh process?
I just commented out the root function invocation, with useEffect still intact and the simulator hung up in the middle of the function execution. But I don’t think I reloaded the terminal. I think that was a live reload thing.
After a manual terminal reload, same result. The function does not complete.
The onClick handler does not complete either.
I’m attempting stopping the bundler and rebuilding the app entirely.
After the stop and rebuild, the function again does not complete from useEffect or from the click handler.
Okay this is weird, when I open “debug mode” from React native, the function completes! When I disable it, the function never completes again.
I’ve added logs throughout the async function that doest the crypto operation. On the first invocation, the one from
useEffect the function passes the first couple of
await keywords, but dies while encrypting. On subsequent executions, with the button press, the function dies right after starting, before any
await statements run.
Removing async / await
I’ve refactored the async function to just use the promise API directly instead of being an async function. Previously the test function I was running was defined as an async function and executed from within the react component with a
.then chain, as if it were just a promise. If I understand correctly, async functions should behave the same way to the caller as a function returning a promise would. I guess this is not the case here.
Now both the
useEffect and the
onClick callbacks work without issue, including when I comment-in and comment-out the root level invocation.
Call for Insight
Dear reader, do you have any insight into why removing the
async syntax, and switching to promise chaining would have fixed my issue above? This is a typescript project generated with
expo mode, and then
ejected. Please send me a message or leave a comment if you have wisdom to share here.