Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memoize StripeTerminalProvider values #221

Merged
merged 7 commits into from
Mar 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"private": true,
"scripts": {
"android": "react-native run-android",
"android:all": "concurrently \"yarn start\" \"yarn start:server\" \"yarn ios\"",
"android:all": "concurrently \"yarn start\" \"yarn start:server\" \"yarn android\"",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops

"bootstrap": "cd .. && yarn bootstrap",
"build:server": "babel server --out-dir dist --extensions '.ts,.tsx' --ignore '**/__tests__/**' --source-maps --copy-files --delete-dir-on-start",
"ios": "react-native run-ios",
Expand Down
46 changes: 22 additions & 24 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import React, { useCallback, useMemo, useEffect, useState } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import {
createStackNavigator,
Expand Down Expand Up @@ -101,10 +101,21 @@ const screenOptions = {

export default function App() {
const [logs, setlogs] = useState<Log[]>([]);
const clearLogs = () => setlogs([]);
const clearLogs = useCallback(() => setlogs([]), []);
const { initialize: initStripe } = useStripeTerminal();

useEffect(() => {
const handlePermissionsSuccess = async () => {
const { error } = await initStripe({
logLevel: 'verbose',
});
if (error) {
Alert.alert('StripeTerminal init failed', error.message);
} else {
console.log('StripeTerminal has been initialized properly');
}
};

async function handlePermissions() {
try {
const granted = await PermissionsAndroid.request(
Expand Down Expand Up @@ -157,31 +168,19 @@ export default function App() {
} else {
handlePermissionsSuccess();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
}, [initStripe]);

const handlePermissionsError = () => {
console.error(
'Location and BT services are required in order to connect to a reader.'
);
};

const handlePermissionsSuccess = async () => {
const { error } = await initStripe({
logLevel: 'verbose',
});
if (error) {
Alert.alert('StripeTerminal init failed', error.message);
} else {
console.log('StripeTerminal has been initialized properly');
}
};

const hasGrantedPermission = (status: string) => {
return status === PermissionsAndroid.RESULTS.GRANTED;
};

const addLogs = (newLog: Log) => {
const addLogs = useCallback((newLog: Log) => {
const updateLog = (log: Log) =>
log.name === newLog.name
? { name: log.name, events: [...log.events, ...newLog.events] }
Expand All @@ -191,16 +190,15 @@ export default function App() {
? prev.map(updateLog)
: [...prev, newLog]
);
};
}, []);

const value = useMemo(
() => ({ logs, addLogs, clearLogs }),
[logs, addLogs, clearLogs]
);

return (
<LogContext.Provider
value={{
logs,
addLogs,
clearLogs,
}}
>
<LogContext.Provider value={value}>
<>
<StatusBar
backgroundColor={colors.blurple_dark}
Expand Down
7 changes: 3 additions & 4 deletions example/src/screens/DiscoverReadersScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ export default function DiscoverReadersScreen() {
});
}, [navigation, cancelDiscovering, discoveringLoading, handleGoBack]);

const handleDiscoverReaders = async () => {
const handleDiscoverReaders = useCallback(async () => {
setDiscoveringLoading(true);
// List of discovered readers will be available within useStripeTerminal hook
const { error: discoverReadersError } = await discoverReaders({
Expand All @@ -138,13 +138,12 @@ export default function DiscoverReadersScreen() {
navigation.goBack();
}
}
};
}, [navigation, discoverReaders, discoveryMethod, simulated]);

useEffect(() => {
simulateReaderUpdate('none');
handleDiscoverReaders();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
}, [handleDiscoverReaders, simulateReaderUpdate]);

const handleConnectReader = async (reader: Reader.Type) => {
let error: StripeError | undefined;
Expand Down
3 changes: 1 addition & 2 deletions example/src/screens/LocationListScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ export default function LocationListScreen() {
}
}
init();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
}, [getLocations]);

const renderItem = (item: Location) => (
<ListItem
Expand Down
15 changes: 7 additions & 8 deletions example/src/screens/ReadReusableCardScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useNavigation } from '@react-navigation/core';
import React, { useContext, useEffect } from 'react';
import React, { useContext, useEffect, useCallback } from 'react';
import { ScrollView, StyleSheet } from 'react-native';
import { useStripeTerminal } from 'stripe-terminal-react-native';
import { colors } from '../colors';
Expand Down Expand Up @@ -36,12 +36,7 @@ export default function ReadReusableCardScreen() {
},
});

useEffect(() => {
_readReusableCard();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

const _readReusableCard = async () => {
const _readReusableCard = useCallback(async () => {
clearLogs();
navigation.navigate('LogListScreen');

Expand Down Expand Up @@ -93,7 +88,11 @@ export default function ReadReusableCardScreen() {
],
});
}
};
}, [navigation, readReusableCard, addLogs, clearLogs]);

useEffect(() => {
_readReusableCard();
}, [_readReusableCard]);

return <ScrollView contentContainerStyle={styles.container} />;
}
Expand Down
195 changes: 104 additions & 91 deletions example/src/screens/SetupIntentScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { RouteProp, useNavigation, useRoute } from '@react-navigation/core';
import React, { useContext, useEffect } from 'react';
import React, { useCallback, useContext, useEffect } from 'react';
import { ScrollView, StyleSheet } from 'react-native';
import {
SetupIntent,
Expand Down Expand Up @@ -50,11 +50,6 @@ export default function SetupIntentScreen() {
},
});

useEffect(() => {
_createSetupIntent();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

const createServerSetupIntent = async () => {
try {
const response = await fetch(`${API_URL}/create_setup_intent`, {
Expand All @@ -71,7 +66,97 @@ export default function SetupIntentScreen() {
}
};

const _createSetupIntent = async () => {
const _processPayment = useCallback(
async (setupIntentId: string) => {
addLogs({
name: 'Process Payment',
events: [
{
name: 'Process',
description: 'terminal.confirmSetupIntent',
metadata: { setupIntentId },
},
],
});
const { setupIntent, error } = await confirmSetupIntent(setupIntentId);
if (error) {
addLogs({
name: 'Process Payment',
events: [
{
name: 'Failed',
description: 'terminal.confirmSetupIntent',
metadata: {
errorCode: error.code,
errorMessage: error.message,
},
},
],
});
} else if (setupIntent) {
addLogs({
name: 'Process Payment',
events: [
{
name: 'Finished',
description: 'terminal.confirmSetupIntent',
metadata: { setupIntentId: setupIntent.id },
},
],
});
}
},
[addLogs, confirmSetupIntent]
);

const _collectPaymentMethod = useCallback(
async (setupIntentId: string) => {
addLogs({
name: 'Collect Setup Intent',
events: [
{
name: 'Collect',
description: 'terminal.collectSetupIntentPaymentMethod',
metadata: { setupIntentId },
},
],
});
const { setupIntent, error } = await collectSetupIntentPaymentMethod({
setupIntentId: setupIntentId,
customerConsentCollected: true,
});
if (error) {
addLogs({
name: 'Collect Setup Intent',
events: [
{
name: 'Failed',
description: 'terminal.collectSetupIntentPaymentMethod',
metadata: {
errorCode: error.code,
errorMessage: error.message,
},
},
],
});
} else if (setupIntent) {
addLogs({
name: 'Collect Setup Intent',
events: [
{
name: 'Created',
description: 'terminal.collectSetupIntentPaymentMethod',
metadata: { setupIntentId: setupIntent.id },
},
],
});
await _processPayment(setupIntentId);
}
},
[_processPayment, addLogs, collectSetupIntentPaymentMethod]
);

const _createSetupIntent = useCallback(async () => {
clearLogs();
navigation.navigate('LogListScreen');
addLogs({
Expand Down Expand Up @@ -129,91 +214,19 @@ export default function SetupIntentScreen() {
} else if (setupIntent) {
await _collectPaymentMethod(setupIntent.id);
}
};

const _collectPaymentMethod = async (setupIntentId: string) => {
addLogs({
name: 'Collect Setup Intent',
events: [
{
name: 'Collect',
description: 'terminal.collectSetupIntentPaymentMethod',
metadata: { setupIntentId },
},
],
});
const { setupIntent, error } = await collectSetupIntentPaymentMethod({
setupIntentId: setupIntentId,
customerConsentCollected: true,
});
if (error) {
addLogs({
name: 'Collect Setup Intent',
events: [
{
name: 'Failed',
description: 'terminal.collectSetupIntentPaymentMethod',
metadata: {
errorCode: error.code,
errorMessage: error.message,
},
},
],
});
} else if (setupIntent) {
addLogs({
name: 'Collect Setup Intent',
events: [
{
name: 'Created',
description: 'terminal.collectSetupIntentPaymentMethod',
metadata: { setupIntentId: setupIntent.id },
},
],
});
await _processPayment(setupIntentId);
}
};
}, [
_collectPaymentMethod,
createSetupIntent,
addLogs,
clearLogs,
discoveryMethod,
navigation,
retrieveSetupIntent,
]);

const _processPayment = async (setupIntentId: string) => {
addLogs({
name: 'Process Payment',
events: [
{
name: 'Process',
description: 'terminal.confirmSetupIntent',
metadata: { setupIntentId },
},
],
});
const { setupIntent, error } = await confirmSetupIntent(setupIntentId);
if (error) {
addLogs({
name: 'Process Payment',
events: [
{
name: 'Failed',
description: 'terminal.confirmSetupIntent',
metadata: {
errorCode: error.code,
errorMessage: error.message,
},
},
],
});
} else if (setupIntent) {
addLogs({
name: 'Process Payment',
events: [
{
name: 'Finished',
description: 'terminal.confirmSetupIntent',
metadata: { setupIntentId: setupIntent.id },
},
],
});
}
};
useEffect(() => {
_createSetupIntent();
}, [_createSetupIntent]);

return <ScrollView contentContainerStyle={styles.container} />;
}
Expand Down
Loading