#Mole-expo-reactnative

1 messages · Page 1 of 1 (latest)

proper peak
#

hello, can you give me more details? like what is broken, what error do you see, etc

woven tendon
#

Hi @proper peak ! yeah, in this section mi app its broke

function App() {
const { initialize } = useStripeTerminal();

useEffect(() => { //this useEffect crashes my app
initialize({
logLevel: 'verbose',
});
}, [initialize]);

return <View />;
}

Exactly, what happens is that the app opens, but when it makes the connection with the stripe SDK it crashes, my production enviroment is a Raspberry pi 4 with lineageOS 18.1 (Android 11) and im using React Native: 0.69.4
Expo: 46
React: 18
Reader: WisePad 3

If this info cant help you here is my repo: https://github.com/EliasLeguizamon123/stripe-integration-reactNative-Expo

proper peak
woven tendon
#

Yes, i have install LineageOS 18.1 and says to who is like Android 11, (im new in Android/mobile apps)

#

In this link you pass describes the requeriments to work:

Android
Android 5.0 (API level 21) and above
compileSdkVersion = 31
targetSdkVersion = 31

This requeriments are minimum or only works if i have Android 5.0 ?

proper peak
#

those are min requirements

#

so API level 21 or higher is required

woven tendon
#

ok, i think i have higher API level, becouse i have Android 11

#

So i cover the min requeriments for using sdk for react native

proper peak
#

ah sorry I misread that, I thought you had Android API lvl 11, but you're on Android 11.0

I never understand Android's API naming convention, there's too many moving parts!

I assume you've followed the steps here https://stripe.com/docs/terminal/payments/setup-integration?terminal-sdk-platform=react-native&terminal-rn-sdk-platform=android#initialize

to set up <StripeTerminalProvider> outer to the <App> component?

Set up a Stripe Terminal SDK or server-driven integration to accept in-person payments.

patent knoll
#

the initialize call is asynchronous. useEffect can only use a synchronous function.

#

(this is fundamental to React)

#

You can get around this using a "self-executing" closure

#
 useEffect(() => {         //this useEffect crashes my app
    (async () => {
        initialize({
        logLevel: 'verbose',
        });
    })();
  }, [initialize]);
#

This is a frequent problem for (newer) React users

proper peak
#

@patent knoll hello and thanks for weighing in! I'm not as familiar with React/ReactNative unfortunately so appreciate your help.

Would that be a code snippet issue in Stripe's docs then, cause the docs don't self execute useEffect()? basically, the snippet above is from the Stripe docs as is (not your snippet)

woven tendon
#

Hi @patent knoll , thanks for your help! let me check with these changes in my code.

patent knoll
#

Could well be; I haven't looked at it. It's an oddness of react where it's very context-specific - if other processes delay the "lifecycle" loop, the initialize might have enough time to finish

#

Just looked - in the example, declaring the init function, and then executing it on the next line, performs the exact same thing

woven tendon
proper peak
patent knoll
#

re: the documentation,

useEffect(() => {
    async function init() {
        ... //init stuff
    };
  init();
}, []);

useEffect(() => {
    (async () => {
        ...//init stuff
    })();
})

both do the same thing

woven tendon
#

When you call to useStripeTerminal to discover Readers in docs describes :
didUpdateDiscoveredReaders: (readers) => {} but this doesnt work in my case, so i read the api reference and discover what it recommends using onUpdateDiscoveredReaders, changing this line it works for me to see readers.

#

@patent knoll i trying adding async into this arrow function and still broken my app

patent knoll
#

Can you show the code? You can't make a useEffect asynchronous; just make an closure within it...

woven tendon
patent knoll
#

Nope, not gonna do all that. Small clip here (note I don't work for Stripe)

woven tendon
#

oh sorry for my misunderstanding, my complete component code is :

export default function Index() {
    const { initialize } = useStripeTerminal();

    useEffect(async () => {
        initialize({
            logLevel: 'verbose',
        })
    }, [initialize])
    return <View />
}
#

Im calling it inside App.js:

function App (){
//do something
return (
    <StripeTerminalProvider
    logLevel='verbose'
    tokenProvider={fetchTokenProvider}>
      <Index />
    </StripeTerminalProvider>
  )}
patent knoll
#

UseEffect lesson:
useEffect expects to be, and must be, called with a SYNCHRONOUS function

useEffect()
useEffect(()=> {})

IF the synchronous function returns a function, the React lifecycle will call said function when the component unmounts.

As such, you CANNOT do

useEffect(async () => {});

IF you call an Asynchronous function within the useEffect call:

useEffect(() => {
    somethingAsynchronous();
})

a promise will be returned, the "arrow function" will be closed, and the underlying asynchronous call dumped.

BUT if you do

useEffect(() => {
    (async () => {
        somethingAsynchronous();
    })();
})
#

the inner (async () => {}) returns a function; the following () executes that function in a closure - an independent, closed code environment, in effect

#

as such, said "self-executing" (the "();") code continues to run after the useEffect synchronously exits

#

a thorough understanding of promises, synchronous and asynchronous code, closures and the useEffect lifesycle are pretty critical to using React

#

(you can get away with a LOT of functionality in a useEffect if you understand these limitations)

#

net: where you put that "async" matters - a lot.