Skip to main content

Getting Started with React Native SDK

Get started with the Reachu React Native SDKin your React Native application. This guide will walk you through installation, configuration, and creating your first shopping cart.

Prerequisites

Before you begin, ensure you have:

  • React Native0.60 or higher
  • Node.js14 or higher
  • Reachu API credentials(API key and GraphQL endpoint)
  • TypeScript(recommended but not required)

Installation

Step 1: Install the SDK

Install the Reachu React Native SDK using your preferred package manager:

npm
npm install @reachu/react-native-sdk

yarn
yarn add @reachu/react-native-sdk

Step 2: Install Required Dependencies

The SDK uses Apollo Client for GraphQL operations and Axios for REST calls. These are automatically installed as dependencies.

Step 3: Environment Configuration

For secure API key management, install react-native-config:

npm
npm install react-native-config

yarn
yarn add react-native-config

Configuration

Step 1: Create Environment File

Create a .env file in your project root:

.env
GRAPHQL_ENDPOINT=https://graph-ql-dev.reachu.io
API_KEY=Bearer <YOUR_API_TOKEN>

Security Note

Never commit your .env file to version control. Add it to your .gitignore file.

Step 2: Create SDK Service

Create a singleton service to manage the SDK instance:

src/services/SdkService.ts
import Config from 'react-native-config';
import SdkClient from '@reachu/react-native-sdk';

class SdkService {
private static _instance: SdkService;
public sdk: SdkClient;

private constructor() {
this.sdk = new SdkClient(
Config.API_KEY!,
Config.GRAPHQL_ENDPOINT!
);
}

static get instance() {
if (!this._instance) {
this._instance = new SdkService();
}
return this._instance;
}
}

// Export the singleton instance
export default SdkService.instance;

Basic Usage

Initialize and Use the SDK

App.tsx
import React, { useEffect, useState } from 'react';
import {
SafeAreaView,
ScrollView,
StatusBar,
StyleSheet,
Text,
useColorScheme,
View,
Button,
Alert,
} from 'react-native';

import SdkService from './src/services/SdkService';

function App(): JSX.Element {
const [cartId, setCartId] = useState<string | null>(null);
const [loading, setLoading] = useState(false);

const createCart = async () => {
try {
setLoading(true);
const cart = await SdkService.sdk.cart.create({
customer_session_id: Date.now().toString(),
currency: 'USD',
});

setCartId(cart.cart_id);
Alert.alert('Success', `Cart created with ID: ${cart.cart_id}`);
} catch (error) {
console.error('Error creating cart:', error);
Alert.alert('Error', 'Failed to create cart');
} finally {
setLoading(false);
}
};

const addItemToCart = async () => {
if (!cartId) {
Alert.alert('Error', 'Please create a cart first');
return;
}

try {
setLoading(true);
// First, get available products
const products = await SdkService.sdk.channel.product.get({
currency: 'USD',
image_size: 'large',
});

if (products.length === 0) {
Alert.alert('Error', 'No products available');
return;
}

// Add the first product to cart
const updatedCart = await SdkService.sdk.cart.addItem({
cart_id: cartId,
line_items: {
product_id: products[0].id,
quantity: 1,
},
});

Alert.alert('Success', 'Item added to cart successfully!');
} catch (error) {
console.error('Error adding item:', error);
Alert.alert('Error', 'Failed to add item to cart');
} finally {
setLoading(false);
}
};

return (
<SafeAreaView style={styles.container}>
<StatusBar barStyle="dark-content" backgroundColor="#ffffff" />
<ScrollView contentInsetAdjustmentBehavior="automatic" style={styles.scrollView}>
<View style={styles.body}>
<Text style={styles.title}>Reachu React Native SDK Demo</Text>

<View style={styles.section}>
<Text style={styles.sectionTitle}>Cart Management</Text>
<Button
title={loading ? "Loading..." : "Create Cart"}
onPress={createCart}
disabled={loading}
/>

{cartId && (
<View style={styles.cartInfo}>
<Text style={styles.cartId}>Cart ID: {cartId}</Text>
<Button
title={loading ? "Loading..." : "Add Item to Cart"}
onPress={addItemToCart}
disabled={loading}
/>
</View>
)}
</View>
</View>
</ScrollView>
</SafeAreaView>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ffffff',
},
scrollView: {
backgroundColor: '#ffffff',
},
body: {
backgroundColor: '#ffffff',
padding: 20,
},
title: {
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
marginBottom: 30,
color: '#333333',
},
section: {
marginBottom: 30,
},
sectionTitle: {
fontSize: 18,
fontWeight: '600',
marginBottom: 15,
color: '#333333',
},
cartInfo: {
marginTop: 15,
padding: 15,
backgroundColor: '#f5f5f5',
borderRadius: 8,
},
cartId: {
fontSize: 14,
color: '#666666',
marginBottom: 10,
},
});

export default App;

Complete Shopping Flow Example

Here's a more comprehensive example showing a complete shopping flow:

src/components/ShoppingFlow.tsx
import React, { useState } from 'react';
import { View, Text, Button, Alert, StyleSheet } from 'react-native';
import SdkService from '../services/SdkService';

export const ShoppingFlow: React.FC = () => {
const [cartId, setCartId] = useState<string | null>(null);
const [checkoutId, setCheckoutId] = useState<string | null>(null);
const [loading, setLoading] = useState(false);

const createCartAndAddItem = async () => {
try {
setLoading(true);

// 1. Create cart
const cart = await SdkService.sdk.cart.create({
customer_session_id: `session_${Date.now()}`,
currency: 'USD',
});
setCartId(cart.cart_id);

// 2. Get products
const products = await SdkService.sdk.channel.product.get({
currency: 'USD',
image_size: 'large',
});

// 3. Add item to cart
await SdkService.sdk.cart.addItem({
cart_id: cart.cart_id,
line_items: {
product_id: products[0].id,
quantity: 2,
},
});

Alert.alert('Success', 'Cart created and item added!');
} catch (error) {
console.error('Error in cart flow:', error);
Alert.alert('Error', 'Failed to create cart or add item');
} finally {
setLoading(false);
}
};

const createCheckout = async () => {
if (!cartId) return;

try {
setLoading(true);

const checkout = await SdkService.sdk.checkout.create({
cart_id: cartId,
});
setCheckoutId(checkout.id);

// Update checkout with billing address
await SdkService.sdk.checkout.update({
checkout_id: checkout.id,
billing_address: {
first_name: 'John',
last_name: 'Doe',
email: 'john.doe@example.com',
address1: '123 Main St',
city: 'New York',
country: 'United States',
country_code: 'US',
zip: '10001',
phone: '+1234567890',
},
shipping_address: {
first_name: 'John',
last_name: 'Doe',
email: 'john.doe@example.com',
address1: '123 Main St',
city: 'New York',
country: 'United States',
country_code: 'US',
zip: '10001',
phone: '+1234567890',
},
buyer_accepts_terms_conditions: true,
buyer_accepts_purchase_conditions: true,
});

Alert.alert('Success', 'Checkout created and updated!');
} catch (error) {
console.error('Error creating checkout:', error);
Alert.alert('Error', 'Failed to create checkout');
} finally {
setLoading(false);
}
};

const initializePayment = async () => {
if (!checkoutId) return;

try {
setLoading(true);

// Create Stripe payment intent
const paymentIntent = await SdkService.sdk.payment.stripeIntent({
checkout_id: checkoutId,
return_ephemeral_key: true,
});

Alert.alert(
'Payment Ready',
`Payment intent created!\nClient Secret: ${paymentIntent.client_secret?.substring(0, 20)}...`
);
} catch (error) {
console.error('Error initializing payment:', error);
Alert.alert('Error', 'Failed to initialize payment');
} finally {
setLoading(false);
}
};

return (
<View style={styles.container}>
<Text style={styles.title}>Complete Shopping Flow</Text>

<View style={styles.step}>
<Text style={styles.stepTitle}>Step 1: Create Cart & Add Item</Text>
<Button
title={loading ? "Processing..." : "Create Cart & Add Item"}
onPress={createCartAndAddItem}
disabled={loading}
/>
{cartId && (
<Text style={styles.info}> Cart ID: {cartId}</Text>
)}
</View>

<View style={styles.step}>
<Text style={styles.stepTitle}>Step 2: Create Checkout</Text>
<Button
title={loading ? "Processing..." : "Create Checkout"}
onPress={createCheckout}
disabled={loading || !cartId}
/>
{checkoutId && (
<Text style={styles.info}> Checkout ID: {checkoutId}</Text>
)}
</View>

<View style={styles.step}>
<Text style={styles.stepTitle}>Step 3: Initialize Payment</Text>
<Button
title={loading ? "Processing..." : "Initialize Stripe Payment"}
onPress={initializePayment}
disabled={loading || !checkoutId}
/>
</View>
</View>
);
};

const styles = StyleSheet.create({
container: {
padding: 20,
},
title: {
fontSize: 20,
fontWeight: 'bold',
marginBottom: 20,
textAlign: 'center',
},
step: {
marginBottom: 25,
padding: 15,
backgroundColor: '#f8f9fa',
borderRadius: 8,
},
stepTitle: {
fontSize: 16,
fontWeight: '600',
marginBottom: 10,
color: '#333',
},
info: {
marginTop: 10,
fontSize: 12,
color: '#28a745',
fontFamily: 'monospace',
},
});

Error Handling

Always wrap SDK calls in try-catch blocks for proper error handling:

Error Handling Example
import SdkService from '../services/SdkService';

const handleSdkOperation = async () => {
try {
const result = await SdkService.sdk.cart.create({
customer_session_id: 'session-123',
currency: 'USD',
});

// Handle success
console.log('Operation successful:', result);
} catch (error) {
// Handle different types of errors
if (error.networkError) {
console.error('Network error:', error.networkError);
Alert.alert('Network Error', 'Please check your internet connection');
} else if (error.graphQLErrors && error.graphQLErrors.length > 0) {
console.error('GraphQL errors:', error.graphQLErrors);
Alert.alert('API Error', error.graphQLErrors[0].message);
} else {
console.error('Unknown error:', error);
Alert.alert('Error', 'Something went wrong');
}
}
};

Next Steps

Now that you have the SDK set up and working, you can:

  1. Explore the API Reference - Learn about all available methods
  2. Check out UI Components - Pre-built React Native components (coming soon)
  3. View Complete Examples - Full application examples
  4. Learn about State Management - Managing app state with the SDK (coming soon)

Troubleshooting

Common Issues

Apollo Client Network Error

Network error: Unexpected end of JSON input

  • Check that your GraphQL endpoint URL is correct
  • Verify your API key is valid and includes "Bearer " prefix if required

Module Not Found Error

Unable to resolve module '@reachu/react-native-sdk'

  • Run npx react-native clean and reinstall dependencies
  • For iOS: cd ios && pod install

Environment Variables Not Loading

Config.API_KEY is undefined

  • Ensure react-native-config is properly installed and linked
  • Check that your .env file is in the project root
  • Restart your Metro bundler after adding environment variables

Getting Help

If you encounter issues:

  1. Check the API Reference for correct method signatures
  2. Look at the Examples for working code
  3. Contact support@reachu.io for technical assistance

What's Next?

Ready to dive deeper? Check out the **API Reference**to learn about all available SDK methods.