React Native


Beginners To Experts


React Native

From Scratch to Expert

Chapter 1: Introduction to React Native

1. What is React Native?

React Native is a JavaScript framework for building cross-platform mobile applications (iOS & Android) using React.

It allows developers to write native mobile applications using React and JavaScript instead of platform-specific languages like Swift (iOS) or Kotlin (Android).


2. Setting Up the Environment

To start with React Native, you need to set up your development environment. There are two main ways to develop a React Native app:

Option 1: Using Expo (Recommended for Beginners)

Expo is a framework and platform that makes it easy to build and run React Native applications without installing Android Studio or Xcode.


Steps to Install Expo CLI:


                
# Install Node.js (if not installed)
# Install Expo CLI
npm install -g expo-cli

# Create a new project
expo init MyFirstApp

# Navigate into the project folder
cd MyFirstApp

# Start the development server
npm start
            

Option 2: Using React Native CLI (For Advanced Users)

This method requires installing Android Studio for Android development and Xcode for iOS development.

Steps to Install React Native CLI:

# Install React Native CLI
npm install -g react-native-cli

# Create a new project
npx react-native init MyFirstApp

# Navigate into the project folder
cd MyFirstApp

# Run the app on an Android emulator
npx react-native run-android

# Run the app on an iOS simulator (Mac only)
npx react-native run-ios
            

3. Creating Your First React Native App

After setting up the environment, let’s create a basic React Native app.

Basic App Structure (App.js)

import React from 'react';
import { View, Text } from 'react-native';

const App = () => {
  return (
   <View>
      <Text>Hello, React Native!</Text>
    </View>
  );
};

export default App;
            

View: The fundamental UI building block, like <div> in web development.

Text: Used to display text in React Native.


Example 1: Running the App

Once the project is created, use the following command to run your app:

# Run on Expo
npm start

# Run on Android Emulator (React Native CLI)
npx react-native run-android

# Run on iOS Simulator (React Native CLI)
npx react-native run-ios
            

4. Understanding React Native Components

React Native provides core components to build UI elements. Some of the most common ones are:

  • View: The most basic container, similar to <div> in HTML.
  • Text: Used for displaying text.
  • Image: Displays images.
  • ScrollView: A scrollable container.
  • TextInput: A field for user input.

Example 2: Basic UI Components

import React from 'react';
import { View, Text, Image, TextInput } from 'react-native';

const App = () => {
  return (
    <View>
      <Text>Hello, Welcome to React Native!</Text>
      <Image 
        source={{ uri: 'https://reactnative.dev/img/tiny_logo.png' }} 
        style={{ width: 50, height: 50 }} 
      />
      <TextInput placeholder="Type here..." />
    </View>
  );
};

export default App;
            

5. Styling in React Native

React Native uses a StyleSheet to style components, similar to CSS but with camelCase properties.


Example 3: Styling with StyleSheet

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

const App = () => {
  return (
   <View style={styles.container}>
  <Text style={styles.text}>Styled Text in React Native</Text>
</View>

  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1, // Takes full height
    justifyContent: 'center', // Center vertically
    alignItems: 'center', // Center horizontally
    backgroundColor: '#f0f0f0',
  },
  text: {
    fontSize: 20,
    fontWeight: 'bold',
    color: 'blue',
  },
});

export default App;
            

6. Running the App on a Device or Emulator

You can test your app on a real device or an emulator.

Example 4: Running on an Emulator

Android: Open Android Studio and start an emulator, then run:

npx react-native run-android
            

iOS: On a Mac, open Xcode and run:

npx react-native run-ios
            

Example 5: Running on a Real Device with Expo

  • Install the Expo Go app on your phone (Android/iOS).
  • Scan the QR code from the terminal using the Expo Go app.

Summary

Topic Description
What is React Native? A JavaScript framework for cross-platform mobile development.
Setting up the Environment Install Node.js, Expo CLI (recommended) or React Native CLI.
Creating a React Native App Initialize a project using expo init or npx react-native init.
Understanding Components Learn core components like View, Text, Image, TextInput.
Styling Components Use StyleSheet for applying styles.
Running the App Run on an emulator, iOS simulator, or real device.

Chapter 2: Core Components in React Native

View Component

The View component is a container used for structuring UI elements, similar to <div> in web development.

Syntax:

<View style={styles.container}>
  {/* Child components go here */}
</View>
            

Common Uses:

  • Grouping multiple components
  • Structuring UI layouts
  • Applying background colors and padding

Example 1: Basic View with Text

import React from 'react';
import { View, Text } from 'react-native';

const App = () => {
  return (
   <View>
      <Text>Hello, React Native!</Text>
    </View>
  );
};

export default App;
            

Example 2: Styling a View

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

const App = () => {
  return (
    <View style={styles.container}>
  <Text style={styles.text}>Styled View</Text>
</View>

  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#f0f0f0',
  },
  text: {
    fontSize: 18,
    color: 'blue',
  },
});

export default App;
            

Example 3: Nested Views

import React from 'react';
import { View, Text } from 'react-native';

const App = () => {
  return (
   <View>
      <View>
        <Text>Inside First View</Text>
      </View>
      <View>
        <Text>Inside Second View</Text>
      </View>
    </View>
  );
};

export default App;
            

Example 4: Flexible Layouts with View

import React from 'react';
import { View, StyleSheet } from 'react-native';

const App = () => {
  return (
    <View style={styles.container}>
  <View style={styles.box1} />
  <View style={styles.box2} />
</View>

  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row',
  },
  box1: {
    flex: 1,
    backgroundColor: 'red',
  },
  box2: {
    flex: 1,
    backgroundColor: 'blue',
  },
});

export default App;
            

Example 5: View with Borders

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

const App = () => {
  return (
    <View style={styles.box}>
  <Text>Box with Border</Text>
</View>

  );
};

const styles = StyleSheet.create({
  box: {
    borderWidth: 2,
    borderColor: 'black',
    padding: 10,
    margin: 10,
  },
});

export default App;
            

2. Text Component

The Text component is used for displaying text in React Native.

Syntax:

<Text style={styles.textStyle}>Hello, World!</Text>
            

Common Uses:

  • Displaying text
  • Styling fonts, size, and alignment
  • Wrapping multiple lines

Example 1: Basic Text

import React from 'react';
import { Text } from 'react-native';

const App = () => {
  return Hello, React Native!;
};

export default App;
            

Example 2: Styled Text

import React from 'react';
import { Text, StyleSheet } from 'react-native';

const App = () => {
  return Styled Text;
};

const styles = StyleSheet.create({
  text: {
    fontSize: 20,
    fontWeight: 'bold',
    color: 'blue',
  },
});

export default App;
            

Example 3: Multiline Text

import React from 'react';
import { Text } from 'react-native';

const App = () => {
  return (
    
      This is a long text that wraps across multiple lines in React Native.
    
  );
};

export default App;
            

Example 4: Text Alignment

import React from 'react';
import { Text, StyleSheet } from 'react-native';

const App = () => {
  return Centered Text;
};

const styles = StyleSheet.create({
  centerText: {
    textAlign: 'center',
    fontSize: 18,
  },
});

export default App;
            

Example 5: Combining Different Text Styles

import React from 'react';
import { Text, StyleSheet } from 'react-native';

const App = () => {
  return (
    
      Bold Text and Italic Text.
    
  );
};

const styles = StyleSheet.create({
  bold: { fontWeight: 'bold' },
  italic: { fontStyle: 'italic' },
});

export default App;
            

3. Image Component

The Image component is used to display images in React Native.

Syntax:

<Image source={{ uri: 'image_url' }} style={styles.image} />

Common Uses:

  • Displaying local and remote images
  • Using images as backgrounds
  • Adjusting image size

Example 1: Displaying a Remote Image

import React from 'react';
import { Image } from 'react-native';

const App = () => {
  return (
    <Image 
      source={{ uri: 'https://reactnative.dev/img/tiny_logo.png' }} 
      style={{ width: 50, height: 50 }} 
    />
);

export default App;

Example 2: Displaying a Local Image

import React from 'react';
import { Image } from 'react-native';

const App = () => {
  return <Image source={require('./assets/logo.png')} style={{ width: 100, height: 100 }} />
};

export default App;

Example 3: Image with Border Radius

import React from 'react';
import { Image, StyleSheet } from 'react-native';

const App = () => {
  return <Image source={{ uri: 'https://reactnative.dev/img/tiny_logo.png' }} style={styles.image} />
};

const styles = StyleSheet.create({
  image: {
    width: 100,
    height: 100,
    borderRadius: 50,
  },
});

export default App;

Chapter 3: Handling User Input & Events in React Native

Handling user input is essential in mobile applications. React Native provides several ways to manage user interactions, such as buttons, text input fields, touch gestures, and lists. This chapter covers:

  • Button Component
  • TouchableOpacity
  • TextInput
  • ScrollView
  • FlatList
  • SectionList
  • Keyboard Handling

Each section will include fully commented code and 7 simple examples to reinforce understanding.

1. Button Component

The Button component in React Native is used to create a simple pressable button with built-in styling.

Syntax:

<Button title="Click Me" onPress={myFunction} />
Example 1: Basic Button
import React from 'react';
import { View, Button } from 'react-native';

const App = () => {
  // Function to execute when button is pressed
  const handlePress = () => {
    alert('Button Pressed!');
  };

  return (
    <View>
      <Button title="Click Me" onPress={handlePress} />
    </View>
  );
};

export default App;
Example 2: Button with Different Titles
import React from 'react';
import { View, Button } from 'react-native';

const App = () => {
  return (
    <View>
      <Button title="Submit" onPress={() => alert('Submitted!')} />
      <Button title="Cancel" onPress={() => alert('Canceled!')} />
    </View>
  );
};

export default App;
Example 3: Button with Color
import React from 'react';
import { View, Button } from 'react-native';

const App = () => {
  return (
    <View>
      <Button title="Red Button" color="red" onPress={() => alert('Red Button Pressed!')} />
    </View>
  );
};

export default App;
Example 4: Button Inside a Styled View
import React from 'react';
import { View, Button, StyleSheet } from 'react-native';

const App = () => {
  return (
    <View style={styles.container}>
      <Button title="Styled Button" onPress={() => alert('Button Pressed!')} />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    margin: 20,
    padding: 10,
    backgroundColor: '#f0f0f0',
    borderRadius: 10,
  },
});

export default App;
Example 5: Multiple Buttons in a Column
import React from 'react';
import { View, Button } from 'react-native';

const App = () => {
  return (
    <View>
      <Button title="Button 1" onPress={() => alert('Button 1 Pressed!')} />
      <Button title="Button 2" onPress={() => alert('Button 2 Pressed!')} />
      <Button title="Button 3" onPress={() => alert('Button 3 Pressed!')} />
    </View>
  );
};

export default App;
Example 6: Disabling a Button
import React from 'react';
import { View, Button } from 'react-native';

const App = () => {
  return (
    <View>
      <Button title="Disabled Button" disabled onPress={() => alert('Button Pressed!')} />
    </View>
  );
};

export default App;
Example 7: Button with a Custom Function
import React from 'react';
import { View, Button } from 'react-native';

const App = () => {
  const showMessage = (message) => {
    alert(message);
  };

  return (
    <View>
      <Button title="Show Message" onPress={() => showMessage('Hello, React Native!')} />
    </View>
  );
};

export default App;

2. TouchableOpacity (Custom Buttons)

TouchableOpacity is a more customizable button that provides visual feedback when pressed.

Syntax:

<TouchableOpacity onPress={myFunction}>
  <Text>Click Me</Text>
</TouchableOpacity>

Examples:

Example 1: Basic TouchableOpacity

import React from 'react';
import { View, Text, TouchableOpacity } from 'react-native';

const App = () => {
  return (
    <View>
      <TouchableOpacity onPress={() => alert('Touchable Pressed!')}>
        <Text>Press Me</Text>
      </TouchableOpacity>
    </View>
  );
};

export default App;

Example 2: Styled TouchableOpacity

import React from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';

const App = () => {
  return (
    <View>
      <TouchableOpacity style={styles.button} onPress={() => alert('Styled Button Pressed!')}>
        <Text style={styles.text}>Press Me</Text>
      </TouchableOpacity>
    </View>
  );
};

const styles = StyleSheet.create({
  button: {
    backgroundColor: 'blue',
    padding: 10,
    borderRadius: 5,
  },
  text: {
    color: 'white',
    textAlign: 'center',
  },
});

export default App;

Example 3: TouchableOpacity with Border

import React from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';

const App = () => {
  return (
    <View>
      <TouchableOpacity style={styles.button} onPress={() => alert('Button Pressed!')}>
        <Text style={styles.text}>Bordered Button</Text>
      </TouchableOpacity>
    </View>
  );
};

const styles = StyleSheet.create({
  button: {
    borderWidth: 2,
    borderColor: 'black',
    padding: 10,
    margin: 10,
    borderRadius: 5,
  },
  text: {
    textAlign: 'center',
  },
});

export default App;

Example 4: TouchableOpacity with Image

import React from 'react';
import { View, Image, TouchableOpacity } from 'react-native';

const App = () => {
  return (
    <View>
      <TouchableOpacity onPress={() => alert('Image Pressed!')}>
        <Image 
          source={{ uri: 'https://reactnative.dev/img/tiny_logo.png' }} 
          style={{ width: 50, height: 50 }} 
        />
      </TouchableOpacity>
    </View>
  );
};

export default App;

Example 5: TouchableOpacity with Multiple Actions

import React from 'react';
import { View, Text, TouchableOpacity } from 'react-native';

const App = () => {
  const handlePress = () => {
    alert('You Pressed the Button!');
    console.log('Button Pressed');
  };

  return (
    <View>
      <TouchableOpacity onPress={handlePress}>
        <Text>Press Me</Text>
      </TouchableOpacity>
    </View>
  );
};

export default App;

TextInput in React Native

Overview

The TextInput component is used to receive user input in a text field. It supports various properties like placeholder, secureTextEntry (for passwords), keyboardType, and onChangeText (to handle input changes).

Basic Syntax

<TextInput
  placeholder="Enter text"
  onChangeText={handleInput}
/>

Examples:

Example 1: Basic Text Input

import React, { useState } from 'react';
import { View, TextInput, Text } from 'react-native';

const App = () => {
  const [text, setText] = useState('');

  return (
    <View>
      <TextInput
        placeholder="Type here..."
        onChangeText={setText} // Updates state when text changes
        style={{ borderWidth: 1, padding: 10 }}
      />
      <Text>You typed: {text}</Text>
    </View>
  );
};

export default App;

Example 2: Text Input with Placeholder and Styling

import React, { useState } from 'react';
import { View, TextInput, Text, StyleSheet } from 'react-native';

const App = () => {
  const [text, setText] = useState('');

  return (
    <View>
      <TextInput
        style={styles.input}
        placeholder="Enter your name"
        onChangeText={setText}
      />
      <Text>Hello, {text}!</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  input: {
    borderWidth: 1,
    borderColor: 'gray',
    padding: 10,
    borderRadius: 5,
    margin: 10,
  },
});

export default App;

Example 3: Password Input (Secure Text Entry)

import React, { useState } from 'react';
import { View, TextInput, Text } from 'react-native';

const App = () => {
  const [password, setPassword] = useState('');

  return (
    <View>
      <TextInput
        placeholder="Enter Password"
        secureTextEntry={true} // Hides input text
        onChangeText={setPassword}
        style={{ borderWidth: 1, padding: 10 }}
      />
      <Text>Entered Password: {password}</Text>
    </View>
  );
};

export default App;

Example 4: Numeric Input (Keyboard Type)

import React, { useState } from 'react';
import { View, TextInput, Text } from 'react-native';

const App = () => {
  const [number, setNumber] = useState('');

  return (
    <View>
      <TextInput
        placeholder="Enter a number"
        keyboardType="numeric" // Sets numeric keyboard
        onChangeText={setNumber}
        style={{ borderWidth: 1, padding: 10 }}
      />
      <Text>Number: {number}</Text>
    </View>
  );
};

export default App;

Example 5: Multiline Text Input

import React, { useState } from 'react';
import { View, TextInput, Text } from 'react-native';

const App = () => {
  const [message, setMessage] = useState('');

  return (
    <View>
      <TextInput
        placeholder="Enter your message"
        multiline={true} // Allows multiple lines
        numberOfLines={4} // Sets height
        onChangeText={setMessage}
        style={{ borderWidth: 1, padding: 10, height: 100 }}
      />
      <Text>Message: {message}</Text>
    </View>
  );
};

export default App;

Example 6: Input with Max Length

import React, { useState } from 'react';
import { View, TextInput, Text } from 'react-native';

const App = () => {
  const [text, setText] = useState('');

  return (
    <View>
      <TextInput
        placeholder="Enter max 10 chars"
        maxLength={10} // Limits characters to 10
        onChangeText={setText}
        style={{ borderWidth: 1, padding: 10 }}
      />
      <Text>Input: {text}</Text>
    </View>
  );
};

export default App;

Example 7: Input with Auto Capitalization

import React, { useState } from 'react';
import { View, TextInput, Text } from 'react-native';

const App = () => {
  const [text, setText] = useState('');

  return (
    <View>
      <TextInput
        placeholder="Type here..."
        autoCapitalize="words" // Capitalizes each word
        onChangeText={setText}
        style={{ borderWidth: 1, padding: 10 }}
      />
      <Text>You typed: {text}</Text>
    </View>
  );
};

export default App;

The ScrollView component allows content to be scrollable.

It's often used when the content exceeds the size of the screen. You can have a vertical or horizontal scroll, and it supports various properties like onEndReached to handle when the user reaches the end of the list.

Basic Syntax:

<ScrollView>
    <YourContentHere />
</ScrollView>

Example 1: Basic ScrollView

import React from 'react';
import { View, Text, ScrollView } from 'react-native';

const App = () => {
    return (
        <ScrollView>
            <Text>Item 1</Text>
            <Text>Item 2</Text>
            <Text>Item 3</Text>
            <Text>Item 4</Text>
            <Text>Item 5</Text>
            <Text>Item 6</Text>
            <Text>Item 7</Text>
        </ScrollView>
    );
};

export default App;
        

Example 2: Horizontal ScrollView

import React from 'react';
import { View, Text, ScrollView } from 'react-native';

const App = () => {
    return (
        <ScrollView horizontal={true}>
            <Text style={{ margin: 10 }}>Item 1</Text>
            <Text style={{ margin: 10 }}>Item 2</Text>
            <Text style={{ margin: 10 }}>Item 3</Text>
            <Text style={{ margin: 10 }}>Item 4</Text>
            <Text style={{ margin: 10 }}>Item 5</Text>
        </ScrollView>
    );
};

export default App;
        

Example 3: Nested ScrollView (Vertical and Horizontal)

import React from 'react';
import { ScrollView, Text } from 'react-native';

const App = () => {
    return (
        <ScrollView>
            <Text>Vertical ScrollView</Text>
            <ScrollView horizontal={true}>
                <Text style={{ margin: 10 }}>Horizontal Item 1</Text>
                <Text style={{ margin: 10 }}>Horizontal Item 2</Text>
            </ScrollView>
            <Text>More Content</Text>
        </ScrollView>
    );
};

export default App;
        

Example 4: ScrollView with Padding and Styling

import React from 'react';
import { View, Text, ScrollView, StyleSheet } from 'react-native';

const App = () => {
    return (
        <ScrollView style={styles.scrollView}>
            <Text style={styles.text}>Item 1</Text>
            <Text style={styles.text}>Item 2</Text>
            <Text style={styles.text}>Item 3</Text>
        </ScrollView>
    );
};

const styles = StyleSheet.create({
    scrollView: {
        padding: 20,
        backgroundColor: '#f0f0f0',
    },
    text: {
        fontSize: 20,
        marginBottom: 10,
    },
});

export default App;
        

Example 5: ScrollView with Images

import React from 'react';
import { ScrollView, Image } from 'react-native';

const App = () => {
    return (
        <ScrollView>
            <Image 
                source={{ uri: 'https://reactnative.dev/img/tiny_logo.png' }} 
                style={{ width: 200, height: 200, marginBottom: 20 }} 
            />
            <Image 
                source={{ uri: 'https://reactnative.dev/img/tiny_logo.png' }} 
                style={{ width: 200, height: 200 }} 
            />
        </ScrollView>
    );
};

export default App;
        

Example 6: ScrollView with Dynamic Content

import React, { useState } from 'react';
import { View, Button, ScrollView, Text } from 'react-native';

const App = () => {
    const [items, setItems] = useState(['Item 1', 'Item 2']);

    const addItem = () => {
        setItems([...items, `Item ${items.length + 1}`]);
    };

    return (
        <View>
            <Button title="Add Item" onPress={addItem} />
            <ScrollView>
                {items.map((item, index) => (
                    <Text key={index}>{item}</Text>
                ))}
            </ScrollView>
        </View>
    );
};

export default App;
        

Example 7: ScrollView with End Reached Event

import React, { useState } from 'react';
import { ScrollView, Text } from 'react-native';

const App = () => {
    const [endReached, setEndReached] = useState(false);

    return (
        <ScrollView
            onEndReached={() => setEndReached(true)}
            onEndReachedThreshold={0.1} 
        >
            <Text>Scroll to the end of this list</Text>
            {endReached && <Text>You have reached the end!</Text>}
        </ScrollView>
    );
};

export default App;
        

FlatList in React Native

The FlatList component is used for rendering a list of data. It is optimized for displaying large lists with better performance than using ScrollView for the same purpose. FlatList only renders the items that are currently visible on the screen, improving memory usage.

Basic Syntax:


<FlatList
  data={yourDataArray}
  renderItem={({ item }) => <YourComponent />}
  keyExtractor={(item, index) => index.toString()}
/>

Example 1: Basic FlatList


import React from 'react';
import { FlatList, Text } from 'react-native';

const App = () => {
  const data = ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5'];

  return (
    <FlatList
      data={data}
      renderItem={({ item }) => <Text>{item}</Text>}
      keyExtractor={(item, index) => index.toString()}
    />
  );
};

export default App;

Example 2: FlatList with Custom Rendering


import React from 'react';
import { FlatList, View, Text, StyleSheet } from 'react-native';

const App = () => {
  const data = ['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry'];

  return (
    <FlatList
      data={data}
      renderItem={({ item }) => (
        <View style={styles.item}>
          <Text style={styles.text}>{item}</Text>
        </View>
      )}
      keyExtractor={(item, index) => index.toString()}
    />
  );
};

const styles = StyleSheet.create({
  item: {
    padding: 10,
    borderBottomWidth: 1,
    borderBottomColor: '#ddd',
  },
  text: {
    fontSize: 18,
  },
});

export default App;

Example 3: FlatList with Images


import React from 'react';
import { FlatList, Image, Text, View, StyleSheet } from 'react-native';

const App = () => {
  const data = [
    { id: '1', image: 'https://reactnative.dev/img/tiny_logo.png' },
    { id: '2', image: 'https://reactnative.dev/img/tiny_logo.png' },
  ];

  return (
    <FlatList
      data={data}
      renderItem={({ item }) => (
        <View style={styles.item}>
          <Image source={{ uri: item.image }} style={styles.image} />
          <Text style={styles.text}>Item {item.id}</Text>
        </View>
      )}
      keyExtractor={(item) => item.id}
    />
  );
};

const styles = StyleSheet.create({
  item: {
    padding: 10,
    borderBottomWidth: 1,
    borderBottomColor: '#ddd',
  },
  image: {
    width: 50,
    height: 50,
    marginBottom: 5,
  },
  text: {
    fontSize: 18,
  },
});

export default App;

Example 4: FlatList with Horizontal Scroll


import React from 'react';
import { FlatList, Text, View } from 'react-native';

const App = () => {
  const data = ['Apple', 'Banana', 'Cherry', 'Date', 'Elderberry'];

  return (
    <FlatList
      data={data}
      horizontal={true} // Enables horizontal scroll
      renderItem={({ item }) => (
        <View style={{ margin: 10 }}>
          <Text>{item}</Text>
        </View>
      )}
      keyExtractor={(item, index) => index.toString()}
    />
  );
};

export default App;

Example 5: FlatList with Refresh Control


import React, { useState } from 'react';
import { FlatList, Text, View, RefreshControl } from 'react-native';

const App = () => {
  const [refreshing, setRefreshing] = useState(false);
  const [data, setData] = useState(['Item 1', 'Item 2', 'Item 3']);

  const onRefresh = () => {
    setRefreshing(true);
    setTimeout(() => {
      setData([...data, `Item ${data.length + 1}`]);
      setRefreshing(false);
    }, 2000);
  };

  return (
    <FlatList
      data={data}
      renderItem={({ item }) => <Text>{item}</Text>}
      keyExtractor={(item, index) => index.toString()}
      refreshControl=<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
    />
  );
};

export default App;

Example 6: FlatList with Item Separator


import React from 'react';
import { FlatList, Text, View, StyleSheet } from 'react-native';

const App = () => {
  const data = ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5'];

  return (
    <FlatList
      data={data}
      renderItem={({ item }) => <Text style={styles.item}>{item}</Text>}
      keyExtractor={(item, index) => index.toString()}
      ItemSeparatorComponent={() => <View style={styles.separator} />}
    />
  );
};

const styles = StyleSheet.create({
  item: {
    padding: 10,
    fontSize: 18,
  },
  separator: {
    height: 1,
    backgroundColor: '#ddd',
  },
});

export default App;

Example 7: FlatList with Infinite Scrolling


import React, { useState } from 'react';
import { FlatList, Text, View } from 'react-native';

const App = () => {
  const [data, setData] = useState(['Item 1', 'Item 2', 'Item 3']);
  const [loading, setLoading] = useState(false);

  const loadMoreData = () => {
    if (!loading) {
      setLoading(true);
      setTimeout(() => {
        setData([...data, `Item ${data.length + 1}`, `Item ${data.length + 2}`]);
        setLoading(false);
      }, 2000);
    }
  };

  return (
    <FlatList
      data={data}
      renderItem={({ item }) => <Text>{item}</Text>}
      keyExtractor={(item, index) => index.toString()}
      onEndReached={loadMoreData}
      onEndReachedThreshold={0.1} // Load more when scrolled near end
    />
  );
};

export default App;

SectionList is ideal for displaying grouped data in sections with headers. Customize sections using renderSectionHeader, renderItem, and renderSectionFooter. You can use horizontal={true} for horizontal sections, and refreshControl for pull-to-refresh functionality. Sections can be dynamic, allowing for changes in content with state management.

Basic Syntax of SectionList in React Native

<SectionList
sections={yourSectionsArray}
renderItem={({ item }) => <YourComponent />}
renderSectionHeader={({ section }) => <YourHeaderComponent />}
keyExtractor={(item, index) => index.toString()}
/>

Example 1: Basic SectionList

import React from 'react';
import { SectionList, Text } from 'react-native';

const App = () => {
  const sections = [
    { title: 'Fruits', data: ['Apple', 'Banana', 'Cherry'] },
    { title: 'Vegetables', data: ['Carrot', 'Lettuce', 'Spinach'] },
  ];

  return (
     {item}}
      renderSectionHeader={({ section }) => {section.title}}
      keyExtractor={(item, index) => index.toString()}
    />
  );
};

export default App;
        

Example 2: SectionList with Custom Header Style

import React from 'react';
import { SectionList, Text, StyleSheet } from 'react-native';

const App = () => {
  const sections = [
    { title: 'Fruits', data: ['Apple', 'Banana', 'Cherry'] },
    { title: 'Vegetables', data: ['Carrot', 'Lettuce', 'Spinach'] },
  ];

  return (
     {item}}
      renderSectionHeader={({ section }) => (
        {section.title}
      )}
      keyExtractor={(item, index) => index.toString()}
    />
  );
};

const styles = StyleSheet.create({
  item: {
    fontSize: 18,
    padding: 10,
  },
  header: {
    fontSize: 22,
    fontWeight: 'bold',
    backgroundColor: '#ddd',
    padding: 5,
  },
});

export default App;
        

Example 3: SectionList with Custom Item Style

import React from 'react';
import { SectionList, Text, StyleSheet } from 'react-native';

const App = () => {
  const sections = [
    { title: 'Fruits', data: ['Apple', 'Banana', 'Cherry'] },
    { title: 'Vegetables', data: ['Carrot', 'Lettuce', 'Spinach'] },
  ];

  return (
     {item}}
      renderSectionHeader={({ section }) => (
        {section.title}
      )}
      keyExtractor={(item, index) => index.toString()}
    />
  );
};

const styles = StyleSheet.create({
  item: {
    fontSize: 18,
    padding: 10,
    backgroundColor: '#f9f9f9',
    borderBottomWidth: 1,
    borderBottomColor: '#ddd',
  },
  header: {
    fontSize: 22,
    fontWeight: 'bold',
    backgroundColor: '#ddd',
    padding: 5,
  },
});

export default App;
        

Example 4: SectionList with Section Footer

import React from 'react';
import { SectionList, Text, View, StyleSheet } from 'react-native';

const App = () => {
  const sections = [
    { title: 'Fruits', data: ['Apple', 'Banana', 'Cherry'], footer: 'More fruits to come!' },
    { title: 'Vegetables', data: ['Carrot', 'Lettuce', 'Spinach'], footer: 'Fresh veggies daily!' },
  ];

  return (
     {item}}
      renderSectionHeader={({ section }) => (
        {section.title}
      )}
      renderSectionFooter={({ section }) => (
        {section.footer}
      )}
      keyExtractor={(item, index) => index.toString()}
    />
  );
};

const styles = StyleSheet.create({
  item: {
    fontSize: 18,
    padding: 10,
    backgroundColor: '#f9f9f9',
    borderBottomWidth: 1,
    borderBottomColor: '#ddd',
  },
  header: {
    fontSize: 22,
    fontWeight: 'bold',
    backgroundColor: '#ddd',
    padding: 5,
  },
  footer: {
    fontSize: 16,
    fontStyle: 'italic',
    backgroundColor: '#f0f0f0',
    padding: 5,
  },
});

export default App;
        

Example 5: SectionList with Horizontal Sections

import React from 'react';
import { SectionList, Text, View, StyleSheet } from 'react-native';

const App = () => {
  const sections = [
    { title: 'Fruits', data: ['Apple', 'Banana', 'Cherry'] },
    { title: 'Vegetables', data: ['Carrot', 'Lettuce', 'Spinach'] },
  ];

  return (
     (
       <View style={styles.item}>
  <Text>{item}</Text>
</View>

      )}
      renderSectionHeader={({ section }) => (
        {section.title}
      )}
      keyExtractor={(item, index) => index.toString()}
    />
  );
};

const styles = StyleSheet.create({
  item: {
    fontSize: 18,
    margin: 10,
    padding: 10,
    backgroundColor: '#ddd',
  },
  header: {
    fontSize: 22,
    fontWeight: 'bold',
    backgroundColor: '#ddd',
    padding: 5,
  },
});

export default App;
        

Example 6: SectionList with Refresh Control

import React, { useState } from 'react';
import { SectionList, Text, View, RefreshControl } from 'react-native';

const App = () => {
  const [refreshing, setRefreshing] = useState(false);
  const [sections, setSections] = useState([
    { title: 'Fruits', data: ['Apple', 'Banana', 'Cherry'] },
    { title: 'Vegetables', data: ['Carrot', 'Lettuce', 'Spinach'] },
  ]);

  const onRefresh = () => {
    setRefreshing(true);
    setTimeout(() => {
      setSections([
        ...sections,
        { title: 'New Section', data: ['Mango', 'Pineapple'] },
      ]);
      setRefreshing(false);
    }, 2000);
  };

  return (
     {item}}
      renderSectionHeader={({ section }) => {section.title}}
      refreshControl={}
      keyExtractor={(item, index) => index.toString()}
    />
  );
};

export default App;
        

Example 7: SectionList with Multiple Sections and Dynamic Content

import React, { useState } from 'react';
import { SectionList, Text, Button, View } from 'react-native';

const App = () => {
  const [sections, setSections] = useState([
    { title: 'Fruits', data: ['Apple', 'Banana', 'Cherry'] },
    { title: 'Vegetables', data: ['Carrot', 'Lettuce', 'Spinach'] },
  ]);

  const addSection = () => {
    setSections([
      ...sections,
      { title: 'Berries', data: ['Strawberry', 'Blueberry', 'Raspberry'] },
    ]);
  };

  return (
     <View>
      <Button title="Add Section" onPress={addSection} />
      <SectionList
        sections={sections}
        renderItem={({ item }) => <Text>{item}</Text>}
        renderSectionHeader={({ section }) => <Text>{section.title}</Text>}
        keyExtractor={(item, index) => index.toString()}
      />
    </View>
  );
};

export default App;
        

Keyboard Handling in React Native

Keyboard handling in React Native is essential for managing how the keyboard interacts with the screen when the user focuses on input fields. The most commonly used components and APIs for keyboard handling are KeyboardAvoidingView, TouchableWithoutFeedback, Keyboard.dismiss(), and TextInput.

Basic Syntax for Keyboard Handling:

import { KeyboardAvoidingView, TextInput, TouchableWithoutFeedback, Keyboard } from 'react-native';

<KeyboardAvoidingView behavior="padding" style={styles.container}>
<TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>
<View>
<TextInput placeholder="Type here" />
</View>
</TouchableWithoutFeedback>
</KeyboardAvoidingView>

Example 1: Using KeyboardAvoidingView with TextInput

import React from 'react';
import { KeyboardAvoidingView, TextInput, StyleSheet, Platform } from 'react-native';

const App = () => {
return (
<KeyboardAvoidingView style={styles.container} behavior={Platform.OS === 'ios' ? 'padding' : 'height'}>
<TextInput placeholder="Type here" style={styles.input} />
</KeyboardAvoidingView>
);
};

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
input: {
height: 40,
borderColor: '#ccc',
borderWidth: 1,
margin: 10,
paddingLeft: 10,
},
});

export default App;

Example 2: Dismissing Keyboard When Tapping Outside

import React from 'react';
import { View, TextInput, TouchableWithoutFeedback, Keyboard, StyleSheet } from 'react-native';

const App = () => {
return (
<TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>
<View style={styles.container}>
<TextInput placeholder="Tap outside to dismiss keyboard" style={styles.input} />
</View>
</TouchableWithoutFeedback>
);
};

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
padding: 20,
},
input: {
height: 40,
borderColor: '#ccc',
borderWidth: 1,
marginBottom: 20,
paddingLeft: 10,
},
});

export default App;

Example 3: KeyboardAvoidingView with Multiple Inputs

import React from 'react';
import { KeyboardAvoidingView, TextInput, StyleSheet, Platform } from 'react-native';

const App = () => {
return (
<KeyboardAvoidingView style={styles.container} behavior={Platform.OS === 'ios' ? 'padding' : 'height'}>
<TextInput placeholder="First Name" style={styles.input} />
<TextInput placeholder="Last Name" style={styles.input} />
</KeyboardAvoidingView>
);
};

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
input: {
height: 40,
borderColor: '#ccc',
borderWidth: 1,
margin: 10,
paddingLeft: 10,
},
});

export default App;

Example 4: Using Keyboard.dismiss() on Button Press

import React from 'react';
import { View, TextInput, Button, StyleSheet, Keyboard } from 'react-native';

const App = () => {
const handleSubmit = () => {
Keyboard.dismiss();
console.log('Form submitted');
};
return (
<View style={styles.container}>
<TextInput placeholder="Type here" style={styles.input} />
<Button title="Submit" onPress={handleSubmit} />
</View>
);
};

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
padding: 20,
},
input: {
height: 40,
borderColor: '#ccc',
borderWidth: 1,
marginBottom: 20,
paddingLeft: 10,
},
});

export default App;

Example 5: Dismissing Keyboard on Button Press

import React, { useState } from 'react';
import { View, TextInput, Button, StyleSheet, Keyboard } from 'react-native';

const App = () => {
const [text, setText] = useState('');
const handleFocus = () => {
console.log('TextInput focused');
};
return (
<View style={styles.container}>
<TextInput
value={text}
onChangeText={setText}
placeholder="Type here"
style={styles.input}
onFocus={handleFocus}
/>
<Button title="Dismiss Keyboard" onPress={() => Keyboard.dismiss()} />
</View>
);
};

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
padding: 20,
},
input: {
height: 40,
borderColor: '#ccc',
borderWidth: 1,
marginBottom: 20,
paddingLeft: 10,
},
});

export default App;

Example 6: KeyboardAvoidingView with ScrollView

import React from 'react';
import { KeyboardAvoidingView, ScrollView, TextInput, Button, StyleSheet, Platform } from 'react-native';

const App = () => {
return (
<KeyboardAvoidingView style={styles.container} behavior={Platform.OS === 'ios' ? 'padding' : 'height'}>
<ScrollView contentContainerStyle={styles.scrollContainer}>
<TextInput placeholder="Type here" style={styles.input} />
<TextInput placeholder="Type more" style={styles.input} />
<Button title="Submit" onPress={() => console.log('Form submitted')} />
</ScrollView>
</KeyboardAvoidingView>
);
};

const styles = StyleSheet.create({
container: {
flex: 1,
},
scrollContainer: {
flexGrow: 1,
justifyContent: 'center',
padding: 20,
},
input: {
height: 40,
borderColor: '#ccc',
borderWidth: 1,
marginBottom: 20,
paddingLeft: 10,
},
});

export default App;

Example 7: Keyboard Handling with Multiple Forms

import React, { useState } from 'react';
import { KeyboardAvoidingView, TextInput, Button, StyleSheet, Platform, Keyboard } from 'react-native';

const App = () => {
const [formData, setFormData] = useState({ name: '', email: '' });
const handleInputChange = (field, value) => {
setFormData({
...formData,
[field]: value,
});
};
const handleSubmit = () => {
Keyboard.dismiss();
console.log('Form Submitted:', formData);
};
return (
<KeyboardAvoidingView style={styles.container} behavior={Platform.OS === 'ios' ? 'padding' : 'height'}>
<TextInput
placeholder="Name"
style={styles.input}
value={formData.name}
onChangeText={(text) => handleInputChange('name', text)}
/>
<TextInput
placeholder="Email"
style={styles.input}
value={formData.email}
onChangeText={(text) => handleInputChange('email', text)}
/>
<Button title="Submit" onPress={handleSubmit} />
</KeyboardAvoidingView>
);
};

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
padding: 20,
},
input: {
height: 40,
borderColor: '#ccc',
borderWidth: 1,
marginBottom: 20,
paddingLeft: 10,
},
});

export default App;

Conclusion

This concludes the examples for Keyboard Handling in React Native. These examples cover the basics of using KeyboardAvoidingView, dismissing the keyboard, handling multiple inputs, and ensuring the keyboard behaves appropriately on different devices.

Chapter 3: State and Props in React Native

In React Native, managing data between components is done using props and state. Props are used to pass data between components, while state is used to manage data within a component. In this chapter, we'll go over these concepts and show examples using simple code snippets.

What is a Hook?

In React and React Native, Hooks are special functions that allow you to "hook into" React's state and lifecycle features from function components. They were introduced in React 16.8 to allow function components to have features that were previously only available in class components, such as managing state, side effects, and context.

Commonly used hooks:

  • useState: To manage state in a functional component.
  • useEffect: To perform side effects (e.g., fetching data, DOM manipulations).
  • useContext: To access context values.
  • useRef: To persist values between renders without triggering re-renders.
  • useReducer: To manage more complex state logic in a component.

useState Hook

The useState hook allows you to add state to a function component. It returns an array with two elements:

  • The current state value.
  • A function to update that state value.

Basic Syntax:

const [state, setState] = useState(initialValue);

state: The current state value.

setState: A function used to update the state.

initialValue: The initial value you want to set for the state.

Example with useState:


import React, { useState } from 'react';
import { Text, Button, View } from 'react-native';

const Counter = () => {
  const [count, setCount] = useState(0); // Declare state 'count' with initial value 0

  return (
   <View>
      <Text>Count: {count}</Text>
      <Button title="Increment" onPress={() => setCount(count + 1)} />
    </View>
  );
};

export default Counter;
    

In this example:

  • We define the count state variable and initialize it with a value of 0.
  • When the button is clicked, the setCount function updates the state, causing the component to re-render with the new count value.

What is State?

In React and React Native, State refers to the data or values that can change during the lifecycle of a component. Unlike props, which are passed from parent to child and are immutable, state is local to a component and can be modified by that component. State allows components to maintain dynamic, interactive behavior.

State is typically used to track things like:

  • User input
  • Toggle states (e.g., show/hide elements)
  • Fetching data from an API
  • Animations and UI changes

In function components, state is managed using the useState hook, while in class components, state is managed using the this.state object and this.setState() method.

Example of State in a Class Component:


import React, { Component } from 'react';
import { Text, Button, View } from 'react-native';

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 }; // Initial state
  }

  increment = () => {
    this.setState({ count: this.state.count + 1 }); // Updating state
  };

  render() {
    return (
     <View>
      <Text>Count: {this.state.count}</Text>
      <Button title="Increment" onPress={this.increment} />
    </View>
    );
  }
}

export default Counter;
    

Key Differences Between Props and State:

Props:

  • Are passed from parent to child components.
  • Are read-only (cannot be modified by the child).
  • Are used to display dynamic data in the UI.

State:

  • Is local to a component.
  • Can be modified within the component.
  • Represents the data that can change over time (e.g., user input, API responses).

Summary:

  • Hooks like useState allow function components to use state and other React features.
  • State is the data that can change over time within a component, used to manage dynamic behavior.
  • Props are immutable and used to pass data from parent components to child components.

1. Understanding Props in React Native

Props are used to pass data from a parent component to a child component. Props are read-only, meaning they can't be modified by the child component, but they can be used to render dynamic content.

Basic Syntax for Props:

const ParentComponent = () => {
  return ;
};

const ChildComponent = (props) => {
  return (
    
      Name: {props.name}, Age: {props.age}
    
  );
};
        

Example 1: Using Props to Display Dynamic Data

import React from 'react';
import { Text, View } from 'react-native';

const ParentComponent = () => {
  return ;
};

const ChildComponent = (props) => {
  return (
    <View>
      <Text>Name: {props.name}</Text>
      <Text>Age: {props.age}</Text>
    </View>
  );
};

export default ParentComponent;
        

Explanation: Here, the ParentComponent passes the name and age as props to the ChildComponent, which then displays them in a Text element.

2. Understanding State in React Native

State is used to manage data that can change over time within a component. Unlike props, state is mutable and can be changed using the useState hook.

Basic Syntax for State:


import React, { useState } from 'react';
import { View, Text } from 'react-native';

const App = () => {
  const [count, setCount] = useState(0);

  return (
   <View>
      <Text>{count}</Text>
      <Button title="Increment" onPress={() => setCount(count + 1)} />
    </View>
  );
};

export default App;
        

Example 2: Changing State with useState


import React, { useState } from 'react';
import { View, Text, Button } from 'react-native';

const App = () => {
  const [count, setCount] = useState(0);

  return (
    <View>
      <Text>Count: {count}</Text>
      <Button title="Increment" onPress={() => setCount(count + 1)} />
      <Button title="Decrement" onPress={() => setCount(count - 1)} />
    </View>
  );
};

export default App;
        

Explanation: This example shows how to use the useState hook to create a count state variable and update it using setCount. The Button components allow the user to increment or decrement the count.

3. Handling user input with state

      
        <TextInput
          value={this.state.input}
          onChangeText={(text) => this.setState({ input: text })}
          placeholder="Type something..."
        />
        <Text>You typed: {this.state.input}</Text>
      
    

4. Updating text dynamically

      
        <Button
          title="Change Text"
          onPress={() => this.setState({ text: "Hello, World!" })}
        />
        <Text>{this.state.text}</Text>
      
    

5. Managing multiple states

      
        <Button
          title="Increment Counter"
          onPress={() => this.setState({ count: this.state.count + 1 })}
        />
        <Text>Counter: {this.state.count}</Text>

        <Button
          title="Change Name"
          onPress={() => this.setState({ name: "John" })}
        />
        <Text>Name: {this.state.name}</Text>
      
    

Handling User Interactions

This section demonstrates how to handle user interactions in React Native, including button clicks, gestures, and text input changes.

  • Handling button clicks
  • Handling gestures (PanResponder)
  • Handling text input changes

Example 1: Handling Button Clicks

This example shows how to handle a button click using the onPress event in React Native.

            {`
            import React, { useState } from 'react';
            import { View, Button, Text } from 'react-native';

            // Function component to handle button click
            const ButtonClickExample = () => {
                // State to track button clicks
                const [count, setCount] = useState(0);

                // Function to increment count when button is pressed
                const handleButtonPress = () => {
                    setCount(count + 1);  // Update count by 1 on every button press
                };

                return (
                    <View style={{ padding: 20 }}>
  <Button title="Click Me!" onPress={handleButtonPress} /> {/* Button that triggers handleButtonPress */}
  <Text>You clicked {count} times</Text>  {/* Display the number of clicks */}
</View>

                );
            };

            export default ButtonClickExample;
            `}
        

Example 2: Using TouchableOpacity for Custom Buttons

This example demonstrates how to use TouchableOpacity to create custom buttons in React Native.

            {`
            import React, { useState } from 'react';
            import { View, TouchableOpacity, Text } from 'react-native';

            // Function component to handle custom button click
            const TouchableOpacityExample = () => {
                const [message, setMessage] = useState('Hello, World!');

                // Function to change message when button is pressed
                const handleChangeMessage = () => {
                    setMessage('You pressed the button!');
                };

                return (
                <View style={{ padding: 20 }}>
  <TouchableOpacity
    style={{
      backgroundColor: '#007BFF',
      padding: 10,
      borderRadius: 5,
    }}
    onPress={handleChangeMessage}  // Trigger message change on press
  >
    <Text style={{ color: 'white', textAlign: 'center' }}>Press Me!</Text>
  </TouchableOpacity>
  <Text>{message}</Text> {/* Display updated message */}
</View>

                );
            };

            export default TouchableOpacityExample;
            `}
        

Example 3: Changing Text Dynamically

This example shows how to change text dynamically when a user interacts with a text input.

            {`
            import React, { useState } from 'react';
            import { View, TextInput, Text } from 'react-native';

            // Function component to handle dynamic text change
            const TextInputExample = () => {
                // State to store text input value
                const [text, setText] = useState('');

                return (
                    <View style={{ padding: 20 }}>
  <TextInput
    style={{
      height: 40,
      borderColor: 'gray',
      borderWidth: 1,
      marginBottom: 20,
      paddingLeft: 8,
    }}
    placeholder="Type something..."
    onChangeText={setText}  // Update state with input text
    value={text}  // Bind text input to state value
  />
  <Text>You typed: {text}</Text>  {/* Dynamically display text entered */}
</View>

                );
            };

            export default TextInputExample;
            `}
        

Example 4: Handling Gestures (PanResponder)

This example demonstrates how to use PanResponder to track and respond to gestures such as dragging.

            {`
            import React, { useState } from 'react';
            import { View, Text, PanResponder } from 'react-native';

            const PanResponderExample = () => {
                // State to track position of the pan gesture
                const [position, setPosition] = useState({ x: 0, y: 0 });

                // PanResponder to track drag gesture
                const panResponder = PanResponder.create({
                    onMoveShouldSetPanResponder: () => true,  // Enable responder for move gestures
                    onPanResponderMove: (event, gestureState) => {
                        // Update position while dragging
                        setPosition({
                            x: gestureState.moveX,
                            y: gestureState.moveY,
                        });
                    },
                    onPanResponderRelease: () => {
                        // Reset position when gesture ends
                        setPosition({ x: 0, y: 0 });
                    },
                });

                return (
                   <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
  <View
    {...panResponder.panHandlers}  // Attach pan responder handlers
    style={{
      width: 100,
      height: 100,
      backgroundColor: '#007BFF',
      position: 'absolute',
      top: position.y - 50,  // Offset to center the box
      left: position.x - 50,  // Offset to center the box
    }}
  />
  <Text>Move the blue box around!</Text>
</View>

                );
            };

            export default PanResponderExample;
            `}
        

Example 5: Handling Long Press Gesture with TouchableWithoutFeedback

This example demonstrates how to handle a long press gesture using TouchableWithoutFeedback in React Native.

            {`
            import React from 'react';
            import { View, Text, TouchableWithoutFeedback } from 'react-native';

            const LongPressExample = () => {
                // Function to handle long press gesture
                const handleLongPress = () => {
                    alert('Long Press Detected!');  // Show an alert on long press
                };

                return (
                   <View style={{ padding: 20 }}>
  <TouchableWithoutFeedback onLongPress={handleLongPress}> 
    {/* Detect long press */}
    <View style={{
      width: 200,
      height: 100,
      backgroundColor: '#28a745',
      justifyContent: 'center',
      alignItems: 'center',
      borderRadius: 10,
    }}>
      <Text style={{ color: 'white' }}>Long Press Me!</Text>
    </View>
  </TouchableWithoutFeedback>
</View>

                );
            };

            export default LongPressExample;
            `}
        

Chapter 5: Navigation in React Native

  • Setting up react-navigation
  • StackNavigator, BottomTabNavigator, DrawerNavigator
  • Passing parameters between screens

Examples:

  1. Setting up navigation
  2. Navigating between screens
  3. Passing data to another screen
  4. Creating a bottom tab navigation
  5. Creating a drawer navigation

1. Setting up navigation

This example shows how to set up navigation in a React Native app using react-navigation:

<import { NavigationContainer } from '@react-navigation/native' />
<import { createStackNavigator } from '@react-navigation/stack' />

<const Stack = createStackNavigator() />

<function App() {>
  <NavigationContainer>
    <Stack.Navigator>
      <Stack.Screen name="Home" component={HomeScreen} />
      <Stack.Screen name="Details" component={DetailsScreen} />
    </Stack.Navigator>
  </NavigationContainer>
<}>

2. Navigating between screens

In this example, we navigate between two screens:

<function HomeScreen({ navigation }) {>
  return (
    <View>
      <Button
        title="Go to Details"
        onPress={() => navigation.navigate('Details')}
      />
    </View>
  )
<}>

3. Passing data to another screen

This example shows how to pass data from one screen to another:

<function HomeScreen({ navigation }) {>
  return (
    <View>
      <Button
        title="Go to Details"
        onPress={() => navigation.navigate('Details', { itemId: 86 })}
      />
    </View>
  )
<}>

<function DetailsScreen({ route }) {>
  const { itemId } = route.params;
  return <Text>Item ID: {itemId}</Text>
<}>

4. Creating a bottom tab navigation

This example demonstrates creating a bottom tab navigation:

<import { createBottomTabNavigator } from '@react-navigation/bottom-tabs' />

<const Tab = createBottomTabNavigator() />

<function App() {>
  return (
    <NavigationContainer>
      <Tab.Navigator>
        <Tab.Screen name="Home" component={HomeScreen} />
        <Tab.Screen name="Settings" component={SettingsScreen} />
      </Tab.Navigator>
    </NavigationContainer>
  )
<}>

5. Creating a drawer navigation

This example demonstrates creating a drawer navigation:

<import { createDrawerNavigator } from '@react-navigation/drawer' />

<const Drawer = createDrawerNavigator() />

<function App() {>
  return (
    <NavigationContainer>
      <Drawer.Navigator>
        <Drawer.Screen name="Home" component={HomeScreen} />
        <Drawer.Screen name="Profile" component={ProfileScreen} />
      </Drawer.Navigator>
    </NavigationContainer>
  )
<}>

Chapter 6: API Calls and Networking

1. Fetching data with fetch

The fetch API is a built-in JavaScript method for making HTTP requests. It is used to get data from external resources (APIs).

Example of using fetch to get data from a public API:

            
                // Fetching data from a public API
                fetch('https://jsonplaceholder.typicode.com/posts')
                    .then(response => response.json()) // Convert response to JSON
                    .then(data => {
                        console.log(data); // Log the data to the console
                    })
                    .catch(error => console.error('Error fetching data:', error)); // Handle errors
            
        

This code fetches a list of posts from a placeholder API and logs the data to the console. The then method handles the response, and catch handles any errors.

2. Fetching data with axios

axios is a popular JavaScript library for making HTTP requests. It simplifies requests and provides additional features over fetch.

Example of using axios to fetch data:

            
                // Using axios to fetch data
                axios.get('https://jsonplaceholder.typicode.com/posts')
                    .then(response => {
                        console.log(response.data); // Log the data to the console
                    })
                    .catch(error => console.error('Error fetching data with axios:', error)); // Handle errors
            
        

This code is similar to the fetch example but uses the axios.get method to fetch data. axios automatically parses the response to JSON.

3. Displaying API data in a list

Once the data is fetched from an API, you can display it in an HTML list. Below is an example of displaying fetched posts in an unordered list:

            
                // Fetching data and displaying it in a list
                fetch('https://jsonplaceholder.typicode.com/posts')
                    .then(response => response.json())
                    .then(data => {
                        const list = document.getElementById('post-list');
                        data.forEach(post => {
                            const li = document.createElement('li');
                            li.textContent = post.title; // Add title to the list item
                            list.appendChild(li); // Append the item to the list
                        });
                    })
                    .catch(error => console.error('Error fetching data:', error));
            
        

In the above example, the data from the API is looped through, and each post's title is added as an item to an unordered list on the page.

4. Handling API errors

Handling errors is essential when working with API requests. You can catch errors like network issues or invalid responses using catch.

Example of handling errors in a fetch request:

            
                fetch('https://jsonplaceholder.typicode.com/invalid-url') // Invalid URL to trigger error
                    .then(response => {
                        if (!response.ok) {
                            throw new Error('Network response was not ok'); // Throw error if response is not OK
                        }
                        return response.json(); // Convert response to JSON
                    })
                    .then(data => console.log(data))
                    .catch(error => {
                        console.error('There was a problem with the fetch operation:', error); // Handle the error
                    });
            
        

This example shows how to handle errors by checking the response status and using catch to log errors when something goes wrong.

5. Fetching data with async/await

The async/await syntax makes working with promises easier and cleaner. Below is an example of fetching data using async/await:

            
                // Using async/await to fetch data
                async function fetchData() {
                    try {
                        const response = await fetch('https://jsonplaceholder.typicode.com/posts');
                        if (!response.ok) {
                            throw new Error('Network response was not ok');
                        }
                        const data = await response.json();
                        console.log(data); // Log the data to the console
                    } catch (error) {
                        console.error('Error fetching data:', error); // Handle errors
                    }
                }

                fetchData(); // Call the function to fetch data
            
        

In this example, the fetchData function uses await to wait for the API response, and try/catch is used to handle errors.

Chapter 7: Animations in React Native

1. Creating a fade-in effect

The Animated API in React Native allows us to create smooth animations. Below is an example of creating a fade-in effect:

            
                // Import the Animated API from React Native
                import { Animated } from 'react-native';
                import React, { useState, useEffect } from 'react';

                const FadeInExample = () => {
                    const fadeAnim = useState(new Animated.Value(0))[0]; // Initialize fade animation with 0 (fully transparent)

                    useEffect(() => {
                        // Trigger the fade-in animation after the component mounts
                        Animated.timing(fadeAnim, {
                            toValue: 1, // Fade to fully opaque
                            duration: 2000, // Duration of 2 seconds
                            useNativeDriver: true, // Use native driver for better performance
                        }).start(); // Start the animation
                    }, []);

                    return (
                        <Animated.View style={{ ...styles.fadeContainer, opacity: fadeAnim }}>
                            <Text>Fade-In Animation</Text>
                        </Animated.View>
                    );
                };

                const styles = {
                    fadeContainer: {
                        alignItems: 'center',
                        justifyContent: 'center',
                        padding: 20,
                        backgroundColor: '#f5f5f5',
                    },
                };

                export default FadeInExample;
            
        

This code demonstrates how to create a fade-in effect where an element fades in from being fully transparent to fully visible.

2. Creating a bounce animation

This example shows how to create a bounce animation using the Animated.spring() method:

            
                import { Animated } from 'react-native';
                import React, { useState, useEffect } from 'react';

                const BounceExample = () => {
                    const bounceAnim = useState(new Animated.Value(1))[0]; // Initial scale of 1

                    useEffect(() => {
                        // Trigger the bounce animation when the component mounts
                        Animated.spring(bounceAnim, {
                            toValue: 1.5, // Scale the element to 1.5 times its original size
                            friction: 2, // Adjust the "bounciness"
                            tension: 150, // Adjust the speed of the bounce
                            useNativeDriver: true, // Use native driver for performance
                        }).start(); // Start the animation
                    }, []);

                    return (
                        <Animated.View style={{ ...styles.bounceContainer, transform: [{ scale: bounceAnim }] }}>
                            <Text>Bounce Animation</Text>
                        </Animated.View>
                    );
                };

                const styles = {
                    bounceContainer: {
                        alignItems: 'center',
                        justifyContent: 'center',
                        padding: 20,
                        backgroundColor: '#f5f5f5',
                    },
                };

                export default BounceExample;
            
        

This example shows how to create a bounce effect where the element scales up and then springs back down using Animated.spring().

3. Moving an object across the screen

Below is an example of moving an object across the screen using Animated.timing():

            
                import { Animated } from 'react-native';
                import React, { useState, useEffect } from 'react';

                const MoveExample = () => {
                    const moveAnim = useState(new Animated.Value(0))[0]; // Starting position

                    useEffect(() => {
                        // Trigger the move animation
                        Animated.timing(moveAnim, {
                            toValue: 300, // Move the object 300 units to the right
                            duration: 2000, // Duration of the animation
                            useNativeDriver: true,
                        }).start(); // Start the animation
                    }, []);

                    return (
                        <Animated.View style={{ ...styles.moveContainer, transform: [{ translateX: moveAnim }] }}>
                            <Text>Move Animation</Text>
                        </Animated.View>
                    );
                };

                const styles = {
                    moveContainer: {
                        alignItems: 'center',
                        justifyContent: 'center',
                        padding: 20,
                        backgroundColor: '#f5f5f5',
                    },
                };

                export default MoveExample;
            
        

This code moves an element across the screen from left to right, using translateX transformation to animate its position.

4. Scaling an image dynamically

This example demonstrates how to scale an image dynamically using Animated.Value and transform:

            
                import { Animated, Image } from 'react-native';
                import React, { useState, useEffect } from 'react';

                const ScaleImageExample = () => {
                    const scaleAnim = useState(new Animated.Value(1))[0]; // Initial scale of 1 (original size)

                    useEffect(() => {
                        // Trigger the scaling animation
                        Animated.timing(scaleAnim, {
                            toValue: 2, // Scale the image to double its size
                            duration: 2000, // Duration of the animation
                            useNativeDriver: true,
                        }).start(); // Start the animation
                    }, []);

                    return (
                        <Animated.View style={{ transform: [{ scale: scaleAnim }] }}>
                            <Image source={{ uri: 'https://placekitten.com/200/300' }} style={{ width: 200, height: 300 }} />
                        </Animated.View>
                    );
                };

                export default ScaleImageExample;
            
        

This code demonstrates how to scale an image, dynamically changing its size from the original to twice its size during the animation.

5. Using LayoutAnimation for smooth transitions

LayoutAnimation provides automatic layout transitions. Below is an example:

            
                import { LayoutAnimation, View, Button, Text } from 'react-native';
                import React, { useState } from 'react';

                const LayoutAnimationExample = () => {
                    const [toggle, setToggle] = useState(false);

                    const handleToggle = () => {
                        LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); // Smooth transition
                        setToggle(!toggle); // Toggle the value
                    };

                    return (
                        <View>
                            <Button title="Toggle View" onPress={handleToggle} />
                            <View style={{ height: toggle ? 100 : 50, backgroundColor: '#f5f5f5', marginTop: 20 }}>
                                <Text>Resize Me!</Text>
                            </View>
                        </View>
                    );
                };

                export default LayoutAnimationExample;
            
        

This example demonstrates using LayoutAnimation to create smooth transitions when a view’s layout changes, such as when its height toggles between two values.

Chapter 8: Managing Global State

1. Using Context API for theme management

Below is an example of using the Context API to manage theme settings in an app:

            
                import React, { createContext, useState, useContext } from 'react';
                import { View, Text, Button } from 'react-native';

                const ThemeContext = createContext(); // Create the context

                const ThemeProvider = ({ children }) => {
                    const [theme, setTheme] = useState('light');

                    const toggleTheme = () => {
                        setTheme(theme === 'light' ? 'dark' : 'light');
                    };

                    return (
                        <ThemeContext.Provider value={{ theme, toggleTheme }}>
                            {children}
                        </ThemeContext.Provider>
                    );
                };

                const ThemedComponent = () => {
                    const { theme, toggleTheme } = useContext(ThemeContext); // Use the context

                    return (
                        <View style={{ backgroundColor: theme === 'light' ? '#fff' : '#333', flex: 1, justifyContent: 'center', alignItems: 'center' }}>
                            <Text style={{ color: theme === 'light' ? '#000' : '#fff' }}>Current theme: {theme}</Text>
                            <Button title="Toggle Theme" onPress={toggleTheme} />
                        </View>
                    );
                };

                const App = () => (
                    <ThemeProvider>
                        <ThemedComponent />
                    </ThemeProvider>
                );

                export default App;
            
        

This code shows how to toggle between light and dark themes using the Context API, providing a shared state to the components.

2. Setting up Redux

Here’s how to set up Redux to manage the global state:

            
                // actions.js
                export const setUser = (user) => ({
                    type: 'SET_USER',
                    payload: user,
                });

                // reducer.js
                const initialState = { user: null };

                const userReducer = (state = initialState, action) => {
                    switch (action.type) {
                        case 'SET_USER':
                            return { ...state, user: action.payload };
                        default:
                            return state;
                    }
                };

                export default userReducer;

                // App.js
                import React from 'react';
                import { Provider, useDispatch, useSelector } from 'react-redux';
                import { createStore } from 'redux';
                import userReducer from './reducer';

                const store = createStore(userReducer); // Create the Redux store

                const App = () => {
                    const dispatch = useDispatch();
                    const user = useSelector(state => state.user); // Get the user from the state

                    const handleSetUser = () => {
                        dispatch({ type: 'SET_USER', payload: { name: 'John Doe' } });
                    };

                    return (
                        <View>
                            <Text>User: {user ? user.name : 'No user set'}</Text>
                            <Button title="Set User" onPress={handleSetUser} />
                        </View>
                    );
                };

                export default () => (
                    <Provider store={store}>
                        <App />
                    </Provider>
                );
            
        

This example demonstrates how to set up Redux by creating actions, reducers, and the Redux store. It shows how to manage a user object in the global state.

3. Fetching and storing global data with Redux

This example shows how to fetch data from an API and store it in Redux:

            
                import { createStore } from 'redux';
                import { Provider, useDispatch, useSelector } from 'react-redux';
                import React, { useEffect } from 'react';
                import { View, Text, Button } from 'react-native';

                const FETCH_DATA = 'FETCH_DATA';

                const fetchData = (data) => ({
                    type: FETCH_DATA,
                    payload: data,
                });

                const dataReducer = (state = { data: [] }, action) => {
                    switch (action.type) {
                        case FETCH_DATA:
                            return { ...state, data: action.payload };
                        default:
                            return state;
                    }
                };

                const store = createStore(dataReducer); // Create Redux store

                const FetchDataComponent = () => {
                    const dispatch = useDispatch();
                    const data = useSelector(state => state.data);

                    useEffect(() => {
                        fetch('https://api.example.com/data')
                            .then((response) => response.json())
                            .then((data) => dispatch(fetchData(data))); // Store the data in Redux
                    }, [dispatch]);

                    return (
                        <View>
                            <Text>Fetched Data:</Text>
                            {data.map((item, index) => (
                                <Text key={index}>{item.name}</Text>
                            ))}
                        </View>
                    );
                };

                export default () => (
                    <Provider store={store}>
                        <FetchDataComponent />
                    </Provider>
                );
            
        

This code demonstrates how to fetch data from an API and store it in Redux, allowing the component to access the data globally.

4. Using Zustand for lightweight state management

Zustand is a lightweight state management tool that can be used as an alternative to Redux. Here’s an example:

            
                import create from 'zustand';

                // Creating a store with Zustand
                const useStore = create((set) => ({
                    theme: 'light',
                    toggleTheme: () => set((state) => ({ theme: state.theme === 'light' ? 'dark' : 'light' })),
                }));

                const App = () => {
                    const { theme, toggleTheme } = useStore(); // Access the global state

                    return (
                        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: theme === 'light' ? '#fff' : '#333' }}>
                            <Text style={{ color: theme === 'light' ? '#000' : '#fff' }}>Current theme: {theme}</Text>
                            <Button title="Toggle Theme" onPress={toggleTheme} />
                        </View>
                    );
                };

                export default App;
            
        

Zustand makes state management easy and simple, as seen here, where we use useStore to manage the theme state with a simple API.

5. Persisting state with AsyncStorage

In this example, we show how to persist state using AsyncStorage:

            
                import { AsyncStorage } from 'react-native';
                import React, { useState, useEffect } from 'react';
                import { View, Text, Button } from 'react-native';

                const App = () => {
                    const [name, setName] = useState('');

                    useEffect(() => {
                        // Fetch the persisted name from AsyncStorage
                        AsyncStorage.getItem('name').then((storedName) => {
                            if (storedName) {
                                setName(storedName);
                            }
                        });
                    }, []);

                    const handleSave = () => {
                        // Persist the name to AsyncStorage
                        AsyncStorage.setItem('name', name);
                    };

                    return (
                        <View>
                            <Text>Saved Name: {name}</Text>
                            <Button title="Save Name" onPress={handleSave} />
                        </View>
                    );
                };

                export default App;
            
        

This example demonstrates how to use AsyncStorage to persist data, allowing it to persist across app reloads.

Chapter 9: Working with Local Storage

Using AsyncStorage: AsyncStorage is a simple, unencrypted, persistent key-value store that is global to the app. It allows storing and retrieving data persistently between app sessions. It is useful for storing small data such as user preferences, app settings, or other basic information.

Saving user preferences: Saving user preferences can be done using AsyncStorage. For example, you can save the user's theme settings, language, or even the last visited screen. This allows the app to maintain the user's choices across app launches.

Retrieving and clearing data: You can retrieve the saved data from AsyncStorage using its getItem() method. You can also clear or remove data with the removeItem() method, which is useful when you want to delete user preferences or other stored data.

1. Saving a string in AsyncStorage

Here’s how you can save a string in AsyncStorage:

            
                import { AsyncStorage } from 'react-native';
                import React, { useState } from 'react';
                import { View, Text, Button } from 'react-native';

                const App = () => {
                    const [name, setName] = useState('');

                    const handleSave = () => {
                        // Save the name string to AsyncStorage
                        AsyncStorage.setItem('userName', name);
                    };

                    return (
                        <View>
                            <Text>Enter your name:</Text>
                            <TextInput
                                placeholder="Name"
                                value={name}
                                onChangeText={setName}
                            />
                            <Button title="Save Name" onPress={handleSave} />
                        </View>
                    );
                };

                export default App;
            
        

This example shows how to save a simple string (the user's name) in AsyncStorage.

2. Retrieving stored data

Here’s how to retrieve stored data from AsyncStorage:

            
                import { AsyncStorage } from 'react-native';
                import React, { useState, useEffect } from 'react';
                import { View, Text, Button } from 'react-native';

                const App = () => {
                    const [name, setName] = useState('');

                    useEffect(() => {
                        // Retrieve the name from AsyncStorage
                        AsyncStorage.getItem('userName').then((storedName) => {
                            if (storedName) {
                                setName(storedName);
                            }
                        });
                    }, []);

                    return (
                        <View>
                            <Text>Stored Name: {name}</Text>
                        </View>
                    );
                };

                export default App;
            
        

This code demonstrates how to retrieve stored data from AsyncStorage and display it in the app.

3. Clearing stored data

In this example, we clear stored data using AsyncStorage:

            
                import { AsyncStorage } from 'react-native';
                import React, { useState } from 'react';
                import { View, Text, Button } from 'react-native';

                const App = () => {
                    const [name, setName] = useState('');

                    const handleClear = () => {
                        // Clear the stored name from AsyncStorage
                        AsyncStorage.removeItem('userName');
                        setName(''); // Clear the state
                    };

                    return (
                        <View>
                            <Text>Stored Name: {name}</Text>
                            <Button title="Clear Stored Name" onPress={handleClear} />
                        </View>
                    );
                };

                export default App;
            
        

This example shows how to remove stored data from AsyncStorage using the removeItem() method.

4. Saving an object in AsyncStorage

In this example, we show how to save an object in AsyncStorage:

            
                import { AsyncStorage } from 'react-native';
                import React, { useState } from 'react';
                import { View, Text, Button } from 'react-native';

                const App = () => {
                    const [user, setUser] = useState({ name: '', age: '' });

                    const handleSave = () => {
                        // Save the user object to AsyncStorage
                        AsyncStorage.setItem('userData', JSON.stringify(user));
                    };

                    return (
                        <View>
                            <Text>Enter your name:</Text>
                            <TextInput
                                placeholder="Name"
                                value={user.name}
                                onChangeText={(text) => setUser({ ...user, name: text })}
                            />
                            <Text>Enter your age:</Text>
                            <TextInput
                                placeholder="Age"
                                value={user.age}
                                onChangeText={(text) => setUser({ ...user, age: text })}
                            />
                            <Button title="Save User" onPress={handleSave} />
                        </View>
                    );
                };

                export default App;
            
        

This code demonstrates how to store an object (user data) in AsyncStorage by stringifying the object before storing it.

5. Using AsyncStorage with state management

Here’s how to use AsyncStorage along with state management:

            
                import { AsyncStorage } from 'react-native';
                import React, { useState, useEffect } from 'react';
                import { View, Text, Button } from 'react-native';

                const App = () => {
                    const [user, setUser] = useState({ name: '', age: '' });

                    useEffect(() => {
                        // Retrieve stored user data and update the state
                        AsyncStorage.getItem('userData').then((data) => {
                            if (data) {
                                setUser(JSON.parse(data));
                            }
                        });
                    }, []);

                    const handleSave = () => {
                        // Save the updated user object to AsyncStorage
                        AsyncStorage.setItem('userData', JSON.stringify(user));
                    };

                    return (
                        <View>
                            <Text>Name: {user.name}</Text>
                            <Text>Age: {user.age}</Text>
                            <Button title="Save User" onPress={handleSave} />
                        </View>
                    );
                };

                export default App;
            
        

This code shows how to combine state management with AsyncStorage to save and retrieve an object, ensuring that the app state is synchronized with local storage.

Chapter 10: Firebase Integration

Setting up Firebase in React Native: Firebase provides a backend-as-a-service (BaaS) platform that includes a real-time database, authentication services, storage, and more. To integrate Firebase into your React Native project, you need to configure Firebase SDK and initialize Firebase in your app. Firebase also provides various services like Cloud Firestore, Firebase Authentication, Cloud Messaging, etc. You'll need to configure Firebase and import necessary SDKs to start using these services.

Using Firestore for real-time database: Firestore is Firebase's NoSQL document-based database, offering flexibility and scalability. It allows you to store, sync, and query data in real-time across all clients. Firestore automatically handles real-time synchronization, making it suitable for applications like chats, live updates, and collaborative applications. Data in Firestore is stored as collections of documents, each containing fields and subcollections.

Authentication with Firebase: Firebase Authentication helps manage users with simple SDKs. It supports various authentication methods like email/password login, Google sign-in, Facebook login, and more. By using Firebase Authentication, you can easily manage user registration, login, and authentication without worrying about the backend. It provides seamless integration with Firestore for user-related data storage.

1. Setting up Firebase

This example shows how to set up Firebase in your React Native project:

            
                // First, install Firebase SDK in your project
                // Run this command in your terminal:
                // npm install --save @react-native-firebase/app

                import { FirebaseApp } from '@react-native-firebase/app';
                
                // Initialize Firebase with the configuration
                const firebaseConfig = {
                    apiKey: 'YOUR_API_KEY',
                    authDomain: 'YOUR_AUTH_DOMAIN',
                    databaseURL: 'YOUR_DATABASE_URL',
                    projectId: 'YOUR_PROJECT_ID',
                    storageBucket: 'YOUR_STORAGE_BUCKET',
                    messagingSenderId: 'YOUR_MESSAGING_SENDER_ID',
                    appId: 'YOUR_APP_ID',
                };

                // Check if Firebase is already initialized
                if (!FirebaseApp.apps.length) {
                    FirebaseApp.initializeApp(firebaseConfig);  // Initialize Firebase with the config object
                }

                console.log("Firebase Initialized");  // Log the initialization status
            
        

This code initializes Firebase in your app by providing the necessary configuration from your Firebase project in the Firebase Console. Make sure to replace the placeholders with your actual Firebase configuration details.

2. Storing data in Firestore

This example demonstrates how to store data in Firestore:

            
                import firestore from '@react-native-firebase/firestore';
                import { View, Text, Button, TextInput } from 'react-native';
                import React, { useState } from 'react';

                const App = () => {
                    const [name, setName] = useState('');

                    const saveData = async () => {
                        // Reference to the 'users' collection in Firestore
                        const usersCollection = firestore().collection('users');
                        
                        // Add a new document to the collection with the name
                        await usersCollection.add({
                            name: name,
                            timestamp: firestore.FieldValue.serverTimestamp(),  // Add timestamp when the document is created
                        });
                        
                        console.log('User added to Firestore');
                    };

                    return (
                        <View>
                            <TextInput
                                placeholder="Enter Name"
                                value={name}
                                onChangeText={setName}
                            />
                            <Button title="Save User" onPress={saveData} />
                        </View>
                    );
                };

                export default App;
            
        

This example demonstrates how to add a new user to the Firestore 'users' collection. It saves the user's name and the timestamp when the document is created in Firestore.

3. Fetching data from Firestore

This example shows how to fetch data from Firestore:

            
                import firestore from '@react-native-firebase/firestore';
                import { View, Text } from 'react-native';
                import React, { useState, useEffect } from 'react';

                const App = () => {
                    const [users, setUsers] = useState([]);

                    useEffect(() => {
                        // Listen for real-time updates from the 'users' collection
                        const unsubscribe = firestore()
                            .collection('users')
                            .onSnapshot(querySnapshot => {
                                const usersList = [];
                                querySnapshot.forEach(documentSnapshot => {
                                    usersList.push(documentSnapshot.data());  // Push the document data to the users list
                                });
                                setUsers(usersList);  // Update the state with fetched data
                            });

                        return () => unsubscribe();  // Unsubscribe when the component unmounts
                    }, []);

                    return (
                        <View>
                            {users.map((user, index) => (
                                <Text key={index}>{user.name}</Text>  // Display each user's name
                            ))}
                        </View>
                    );
                };

                export default App;
            
        

This example listens for real-time changes in the Firestore 'users' collection and updates the UI with the user names whenever the data changes in Firestore.

4. Implementing user authentication

This example demonstrates how to implement user login using Firebase Authentication:

            
                import auth from '@react-native-firebase/auth';
                import { View, Text, Button, TextInput } from 'react-native';
                import React, { useState } from 'react';

                const App = () => {
                    const [email, setEmail] = useState('');
                    const [password, setPassword] = useState('');

                    const handleLogin = async () => {
                        try {
                            // Sign in with email and password using Firebase Authentication
                            await auth().signInWithEmailAndPassword(email, password);
                            console.log('User logged in successfully');
                        } catch (error) {
                            console.error(error.message);  // Log the error if authentication fails
                        }
                    };

                    return (
                        <View>
                            <TextInput
                                placeholder="Email"
                                value={email}
                                onChangeText={setEmail}
                            />
                            <TextInput
                                placeholder="Password"
                                value={password}
                                onChangeText={setPassword}
                                secureTextEntry
                            />
                            <Button title="Login" onPress={handleLogin} />
                        </View>
                    );
                };

                export default App;
            
        

This example shows how to handle user login with Firebase Authentication using email and password. If the login is successful, the user is authenticated.

5. Sending push notifications with Firebase

This example demonstrates how to send push notifications using Firebase Cloud Messaging (FCM):

            
                import messaging from '@react-native-firebase/messaging';
                import { View, Text, Button } from 'react-native';
                import React from 'react';

                const App = () => {
                    const handleSendNotification = async () => {
                        // Request permission for push notifications
                        await messaging().requestPermission();
                        
                        // Get the FCM token to send push notifications to this device
                        const token = await messaging().getToken();
                        
                        console.log('FCM Token:', token);  // Log the token (use this for sending push notifications)

                        // Example to send a push notification
                        messaging().sendMessage({
                            to: token,
                            notification: {
                                title: 'New Message',
                                body: 'You have a new notification',
                            },
                        });

                        console.log('Notification sent');
                    };

                    return (
                        <View>
                            <Button title="Send Notification" onPress={handleSendNotification} />
                        </View>
                    );
                };

                export default App;
            
        

This example demonstrates how to request push notification permissions, get the FCM token for the device, and send a push notification to the device using Firebase Cloud Messaging.

Chapter 11: Advanced Topics

Performance optimization: In React Native, optimizing performance is crucial to ensure the app runs smoothly, especially on low-end devices. Performance bottlenecks can arise due to unnecessary renders, large image sizes, inefficient list rendering, or slow API calls. You can improve performance by using techniques such as memoization, lazy loading, and optimizing list rendering with FlatList or SectionList.

Using useEffect for side effects: The `useEffect` hook is a fundamental part of React and React Native that allows you to perform side effects in your functional components. Side effects include operations such as fetching data, subscriptions, timers, logging, and updating the DOM. `useEffect` runs after every render, but you can control its execution by passing dependencies to it.

Background tasks: Background tasks are operations that continue to run even when the app is not in the foreground, such as sending notifications, syncing data, or processing tasks in the background. React Native has libraries like `react-native-background-fetch` and `react-native-background-task` to help manage background tasks efficiently.

Deep linking: Deep linking enables an app to open a specific screen when a user clicks on a URL or receives a push notification. Deep linking is useful for handling links to content or actions within your app. React Native provides the `Linking` API to handle deep links and URL schemes to navigate to specific app screens.

1. Optimizing performance with useMemo

This example demonstrates how to use the `useMemo` hook to memoize expensive calculations and avoid unnecessary re-renders:

            
                import React, { useMemo, useState } from 'react';
                import { View, Text, Button } from 'react-native';

                const App = () => {
                    const [count, setCount] = useState(0);

                    // Expensive calculation (will be memoized)
                    const expensiveCalculation = useMemo(() => {
                        console.log('Calculating...');
                        return count * 2;
                    }, [count]);  // Only re-compute when 'count' changes

                    return (
                        <View>
                            <Text>Count: {count}</Text>
                            <Text>Expensive Calculation: {expensiveCalculation}</Text>
                            <Button title="Increment" onPress={() => setCount(count + 1)} />
                        </View>
                    );
                };

                export default App;
            
        

The `useMemo` hook memoizes the expensive calculation, preventing it from being recalculated on every render, thus optimizing performance.

2. Using useEffect for API calls

This example shows how to use the `useEffect` hook to make API calls when the component mounts:

            
                import React, { useState, useEffect } from 'react';
                import { View, Text, ActivityIndicator } from 'react-native';

                const App = () => {
                    const [data, setData] = useState(null);
                    const [loading, setLoading] = useState(true);

                    // Fetch data on component mount using useEffect
                    useEffect(() => {
                        const fetchData = async () => {
                            try {
                                const response = await fetch('https://api.example.com/data');
                                const jsonData = await response.json();
                                setData(jsonData);
                            } catch (error) {
                                console.error('Error fetching data:', error);
                            } finally {
                                setLoading(false);
                            }
                        };

                        fetchData();
                    }, []);  // Empty dependency array means this effect runs once (on mount)

                    if (loading) {
                        return <ActivityIndicator size="large" />;  // Show loading indicator
                    }

                    return (
                        <View>
                            <Text>Data: {JSON.stringify(data)}</Text>
                        </View>
                    );
                };

                export default App;
            
        

This example uses `useEffect` to fetch data from an API when the component mounts. The loading state is managed until the data is fetched.

3. Running background tasks

This example shows how to set up background tasks using the `react-native-background-fetch` library:

            
                import React, { useEffect } from 'react';
                import { View, Text } from 'react-native';
                import BackgroundFetch from 'react-native-background-fetch';

                const App = () => {
                    useEffect(() => {
                        // Configure background fetch
                        BackgroundFetch.configure(
                            {
                                minimumFetchInterval: 15,  // Set the interval (in minutes) for background fetch
                                stopOnTerminate: false,    // Keep running even after app is terminated
                                startOnBoot: true,         // Start background fetch after device reboot
                            },
                            async () => {
                                console.log('Background task executed');
                                // Perform background tasks (e.g., syncing data, sending notifications)
                            },
                            error => {
                                console.log('Error in background fetch:', error);
                            }
                        );

                        return () => BackgroundFetch.stop();  // Stop background fetch when component unmounts
                    }, []);

                    return (
                        <View>
                            <Text>Background task is running...</Text>
                        </View>
                    );
                };

                export default App;
            
        

This example configures background tasks to run periodically using `react-native-background-fetch`. The background task will execute even if the app is not in the foreground.

4. Implementing deep linking

This example demonstrates how to handle deep linking in React Native using the `Linking` API:

            
                import React, { useEffect } from 'react';
                import { View, Text, Linking } from 'react-native';

                const App = () => {
                    useEffect(() => {
                        // Handle deep link when app is opened
                        const handleDeepLink = (event) => {
                            const { url } = event;
                            console.log('Deep link opened:', url);
                            // Navigate to the relevant screen based on the deep link
                        };

                        Linking.addEventListener('url', handleDeepLink);  // Listen for deep links

                        // Check if app was opened from a deep link
                        Linking.getInitialURL().then((url) => {
                            if (url) {
                                console.log('App opened with URL:', url);
                            }
                        });

                        return () => Linking.removeEventListener('url', handleDeepLink);  // Clean up listener
                    }, []);

                    return (
                        <View>
                            <Text>Listening for deep links...</Text>
                        </View>
                    );
                };

                export default App;
            
        

This example demonstrates how to use the `Linking` API to handle deep linking in React Native, allowing the app to open specific screens when a URL is clicked.

5. Debugging React Native apps

This example shows how to use React Native's debugging tools to debug an app:

            
                import React, { useEffect } from 'react';
                import { View, Text } from 'react-native';

                const App = () => {
                    useEffect(() => {
                        // Example of a common bug (undefined variable)
                        const undefinedVar = undefined;
                        try {
                            console.log(undefinedVar.property);  // This will throw an error
                        } catch (error) {
                            console.error('Error caught:', error);
                            // Use React Native Debugger or console logs to find issues
                        }
                    }, []);

                    return (
                        <View>
                            <Text>Debugging React Native App</Text>
                        </View>
                    );
                };

                export default App;
            
        

This example demonstrates how to use `console.log()` and `console.error()` to debug React Native apps and catch errors. You can also use tools like React Native Debugger for more advanced debugging features.

Chapter 12: Native Modules and Bridging

Native modules allow you to extend React Native by integrating platform-specific code written in Java or Swift/Objective-C. Bridging is the process of making this native code accessible from JavaScript, which is essential for accessing native features not exposed by React Native itself.

Topics covered:

  • Understanding native code and bridging
  • Writing custom native modules for iOS and Android
  • Communicating between JavaScript and native code
  • Using third-party native libraries

Examples

1. Creating a Custom Native Module for iOS (Swift)

This example demonstrates how to create a custom native module for iOS in Swift that exposes a camera functionality to React Native.

/*
    Swift Code: Create a custom module to access the device's camera.
    This is the iOS (Swift) implementation for React Native.
*/

import UIKit
import AVFoundation
import React

@objc(CameraModule)
class CameraModule: NSObject {

    @objc func captureImage(_ callback: @escaping RCTResponseSenderBlock) {
        // Accessing the camera (just a placeholder for camera logic)
        let camera = UIImage(named: "default.jpg") // Placeholder for actual camera capture logic
        callback([NSNull(), camera?.pngData()])
    }
}

// Bridging to React Native
@objc(CameraModule)
extension CameraModule: RCTBridgeModule {
    static func moduleName() -> String {
        return "CameraModule"
    }
}
            

2. Calling Native Code from JavaScript

Here's how you can call a function written in Swift/Objective-C from your JavaScript code using the NativeModules API.

// JavaScript code calling the native module function
import { NativeModules } from 'react-native';

// Call the captureImage function from CameraModule
NativeModules.CameraModule.captureImage((error, result) => {
    if (error) {
        console.error("Error capturing image: ", error);
    } else {
        console.log("Image captured successfully: ", result);
    }
});
            

3. Handling Errors in Native Modules

This example demonstrates how to handle errors in a native module, allowing React Native to gracefully handle any issues that occur during native operations.

/*
    Swift Code for error handling in native modules.
    This is part of the CameraModule implementation.
*/

import React
import UIKit

@objc(CameraModule)
class CameraModule: NSObject {
    @objc func captureImage(_ callback: @escaping RCTResponseSenderBlock) {
        do {
            // Simulating camera access
            guard let camera = UIImage(named: "default.jpg") else {
                throw NSError(domain: "CameraError", code: 1001, userInfo: [NSLocalizedDescriptionKey: "Unable to access the camera"])
            }
            callback([NSNull(), camera.pngData()])
        } catch let error {
            callback([error.localizedDescription, NSNull()])
        }
    }
}
            

4. Using Native Libraries like React Native Camera

In this example, we integrate the react-native-camera library to access camera functionality on both iOS and Android.

// JavaScript code to use the React Native Camera library
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import { RNCamera } from 'react-native-camera';

export default class CameraScreen extends Component {
  render() {
    return (
      
        
          Camera is ready
        
      
    );
  }
}
            

5. Bridging Between Java and Swift (Cross-Platform Communication)

This example shows how to bridge communication between Java (Android) and Swift (iOS) native modules, allowing data sharing across platforms.

// Java Code (Android)
package com.yourapp;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

public class SharedDataModule extends ReactContextBaseJavaModule {
    SharedDataModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }

    @ReactMethod
    public void sendDataToSwift(String message) {
        // Send data to Swift (iOS)
        // This would involve using the bridge to send data
        // between Android and iOS (platform-specific implementation)
    }

    @Override
    public String getName() {
        return "SharedDataModule";
    }
}
            
// Swift Code (iOS)
import React
import Foundation

@objc(SharedDataModule)
class SharedDataModule: NSObject {
  @objc func receiveDataFromJava(_ message: String) {
    print("Data received from Android: \(message)")
  }

  @objc static func moduleName() -> String {
    return "SharedDataModule"
  }
}
            

Testing in React Native

Testing is crucial to ensure the quality and reliability of mobile applications. React Native provides various tools and approaches for unit testing, end-to-end testing, and mocking components.

Topics covered:

  • Unit testing with Jest
  • End-to-end testing with Detox
  • Mocking API calls and components
  • Writing snapshot tests

Examples

1. Writing Unit Tests with Jest

This example demonstrates how to write a simple Jest test to check if a function or component behaves as expected.

// Jest unit test example
import React from 'react';
import { render } from '@testing-library/react-native';
import MyComponent from './MyComponent'; // Importing the component to test

// Jest test for rendering component
test('it renders the component correctly', () => {
    const { getByText } = render();
    const element = getByText('Hello, World!');
    expect(element).toBeTruthy(); // Verifying that the text is rendered
});
            

2. Running Detox End-to-End Tests

This example demonstrates setting up Detox to test the full flow of the app, simulating user interactions and verifying results.

// Detox end-to-end test example
describe('Login Flow', () => {
    it('should show the login screen', async () => {
        await expect(element(by.id('login-screen'))).toBeVisible();
    });

    it('should log in successfully', async () => {
        await element(by.id('username-input')).typeText('user');
        await element(by.id('password-input')).typeText('password');
        await element(by.id('login-button')).tap();
        await expect(element(by.id('home-screen'))).toBeVisible();
    });
});
            

3. Mocking Network Requests

This example demonstrates how to use jest.mock() to mock an API call, ensuring that your tests don’t hit a real server.

// Jest mock API call example
import { fetchData } from './api';
import { myFunction } from './myFunction';

// Mocking the fetchData API call
jest.mock('./api', () => ({
    fetchData: jest.fn(),
}));

test('it fetches data and updates the state', async () => {
    fetchData.mockResolvedValue({ data: 'mocked data' });

    const result = await myFunction(); // Function that uses fetchData
    expect(result).toBe('mocked data'); // Verifying the result from mocked API
});
            

4. Writing Snapshot Tests for Components

This example demonstrates how to write a snapshot test to verify that the UI of a component remains consistent after changes.

// Jest snapshot test example
import React from 'react';
import { render } from '@testing-library/react-native';
import MyComponent from './MyComponent';

test('it matches the snapshot', () => {
    const { toJSON } = render();
    expect(toJSON()).toMatchSnapshot(); // Verifying that the rendered output matches the snapshot
});
            

5. Testing Redux Actions and Reducers

This example demonstrates how to test Redux actions and reducers to ensure state transitions happen correctly.

// Testing Redux actions and reducers
import { addTodo } from './actions';
import todoReducer from './reducers';

// Jest test for action
test('it creates an addTodo action', () => {
    const expectedAction = {
        type: 'ADD_TODO',
        payload: 'Learn React Native',
    };
    expect(addTodo('Learn React Native')).toEqual(expectedAction); // Verifying the action is created correctly
});

// Jest test for reducer
test('it handles ADD_TODO action', () => {
    const initialState = [];
    const action = {
        type: 'ADD_TODO',
        payload: 'Learn React Native',
    };
    const newState = todoReducer(initialState, action);
    expect(newState).toEqual(['Learn React Native']); // Verifying the state is updated correctly
});
            

Deployment and Distribution

Deployment is the process of making the app available for users on app stores (iOS and Android). React Native supports deploying apps with various configurations, including over-the-air updates.

Topics covered:

  • Building the app for iOS and Android
  • Setting up App Store and Google Play distribution
  • OTA (Over-the-Air) updates with CodePush
  • Handling push notifications

Examples

1. Building a Release Version for iOS

This example demonstrates how to create a production build of your app for iOS using Xcode.

// Steps to create a release build for iOS using Xcode:
// 1. Open your React Native project in Xcode.
// 2. Go to the 'Product' menu and select 'Archive' to create a production build.
// 3. After archiving, select 'Distribute App' to upload to the App Store or to a local device.
            

2. Setting up Google Play Store for Android Distribution

This example demonstrates how to prepare your app for submission to the Google Play Store, including setting up a key store and uploading the APK.

// Steps to prepare an Android app for Google Play distribution:
// 1. Generate a signed APK using the key store:
//    - Create or use an existing keystore file.
//    - Configure your React Native app's build.gradle to use the keystore.
// 2. Build the APK for release using the following command:
//    react-native run-android --variant=release
// 3. Upload the APK to the Google Play Console for submission.
            

3. Implementing OTA Updates Using CodePush

This example demonstrates how to configure CodePush in your app to deliver over-the-air updates for bug fixes or small improvements.

// Steps to configure CodePush for OTA updates:
// 1. Install the CodePush package:
//    npm install --save react-native-code-push
// 2. Link the CodePush module to your app:
//    react-native link react-native-code-push
// 3. In your app, use CodePush to synchronize updates:
//    import CodePush from 'react-native-code-push';
//    let codePushOptions = { checkFrequency: CodePush.CheckFrequency.ON_APP_START };
//    export default CodePush(codePushOptions)(YourApp);
            

4. Integrating Firebase Cloud Messaging for Push Notifications

This example demonstrates how to set up Firebase to send push notifications to your React Native app.

// Steps to integrate Firebase Cloud Messaging (FCM) for push notifications:
// 1. Install Firebase dependencies:
//    npm install --save @react-native-firebase/app @react-native-firebase/messaging
// 2. Link Firebase with your app using the Firebase Console.
// 3. Add the Firebase configuration files to your app (google-services.json for Android, GoogleService-Info.plist for iOS).
// 4. Request permission for push notifications on both iOS and Android:
//    import messaging from '@react-native-firebase/messaging';
//    await messaging().requestPermission();
// 5. Listen for incoming messages:
//    messaging().onMessage(async remoteMessage => {
//      console.log('FCM message received', remoteMessage);
//    });
            

5. Setting up CI/CD for React Native

This example demonstrates how to implement a continuous integration and deployment pipeline to automatically test and deploy your React Native app.

// Steps to set up CI/CD for React Native:
// 1. Choose a CI/CD tool like CircleCI, GitHub Actions, or Bitrise.
// 2. Set up a basic configuration file (e.g., circleci.yml for CircleCI) to automate the build and test process.
// Example CircleCI configuration:
// jobs:
//   build:
//     docker:
//       - image: circleci/python:3.7
//     steps:
//       - checkout
//       - run:
//           name: Install Dependencies
//           command: npm install
//       - run:
//           name: Run Tests
//           command: npm test
// 3. Once tests are passed, set up deployment to the app stores or to a staging environment.
            

React Native and TypeScript

TypeScript adds static typing to JavaScript, which helps prevent bugs and improves development speed by providing early feedback.

Topics covered:

  • Setting up TypeScript in React Native
  • Using TypeScript with components and props
  • Type safety in state and actions
  • TypeScript with Redux and API calls

Examples

1. Setting up TypeScript in a React Native Project

This example demonstrates how to add TypeScript support to a React Native project and configure `tsconfig`.

// Steps to set up TypeScript in a React Native project:
// 1. Install TypeScript and necessary types:
//    npm install --save-dev typescript @types/react @types/react-native
// 2. Add a `tsconfig.json` file to your project with the following configuration:
{
  "compilerOptions": {
    "allowJs": true,
    "noEmit": true,
    "isolatedModules": true,
    "strict": true,
    "jsx": "react-native"
  },
  "include": [
    "src/**/*"
  ]
}
// 3. Rename `.js` files to `.tsx` for React components or `.ts` for non-React files.
            

2. Writing a Typed Functional Component

This example demonstrates how to create a functional component that uses TypeScript for typing props and state.

// Defining the type for props:
interface MyComponentProps {
  name: string;
  age: number;
}

// Defining a functional component with typed props:
const MyComponent: React.FC = ({ name, age }) => {
  return (
    

{name}

Age: {age}

); } export default MyComponent;

3. Typing State and Props in TypeScript

This example demonstrates how to define explicit types for component state and props to avoid runtime errors.

// Defining types for component state and props:
interface CounterState {
  count: number;
}

interface CounterProps {
  initialCount: number;
}

class Counter extends React.Component {
  constructor(props: CounterProps) {
    super(props);
    this.state = { count: props.initialCount };
  }

  increment = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    return (
      

{this.state.count}

); } } export default Counter;

4. Using TypeScript with Redux

This example demonstrates how to set up Redux in a React Native project using TypeScript for actions, reducers, and store.

// Defining types for Redux actions:
interface IncrementAction {
  type: 'INCREMENT';
}

interface DecrementAction {
  type: 'DECREMENT';
}

type CounterAction = IncrementAction | DecrementAction;

// Defining the state type:
interface CounterState {
  count: number;
}

// Reducer function with TypeScript:
const counterReducer = (state: CounterState = { count: 0 }, action: CounterAction): CounterState => {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: state.count - 1 };
    default:
      return state;
  }
};

// Setting up the store with TypeScript:
import { createStore } from 'redux';
const store = createStore(counterReducer);
            

5. Making Type-safe API Calls

This example demonstrates how to define types for API responses and use them in network requests to ensure type safety.

// Defining the type for API response:
interface User {
  id: number;
  name: string;
  email: string;
}

const fetchUser = async (userId: number): Promise => {
  const response = await fetch(`https://api.example.com/users/${userId}`);
  const data: User = await response.json();
  return data;
};

// Calling the API function:
fetchUser(1).then(user => {
  console.log(user.name); // Accessing type-safe properties
});
            

Optimizing App Performance

Performance optimization in React Native involves improving the speed, memory usage, and responsiveness of the app.

Topics covered:

  • Reducing the app bundle size
  • Optimizing re-renders with React.memo
  • Lazy loading screens and components
  • Profiling and optimizing performance using Flipper

Examples

1. Using React.memo for Performance Optimization

This example demonstrates how to use `React.memo` to prevent unnecessary re-renders of components and improve performance.

// Wrapping a component with React.memo to avoid re-renders unless props change:
const MyComponent = React.memo(({ name }) => {
  console.log('Rendering MyComponent');
  return 

{name}

; }); // The component will only re-render if the 'name' prop changes.

2. Implementing Lazy Loading for Screens and Components

This example shows how to implement lazy loading using React’s `Suspense` and `lazy` to load components only when they are needed.

// Using React's lazy and Suspense for lazy loading components:
import React, { Suspense, lazy } from 'react';

const MyLazyComponent = lazy(() => import('./MyLazyComponent'));

const App = () => {
  return (
    Loading...
}> ); };

3. Analyzing Performance with Flipper

This example demonstrates how to use Flipper, a debugging tool, to inspect your app’s performance and diagnose issues.

// Step 1: Install Flipper and connect it to your React Native app.
// Step 2: Enable performance profiling in Flipper by selecting the Performance tab.
// Step 3: Analyze the timeline, CPU usage, and memory usage to identify performance bottlenecks.
// Example: Check for unnecessary re-renders or slow functions causing performance issues.
            

4. Reducing Bundle Size with Hermes

This example shows how to enable Hermes, a JavaScript engine, to reduce the app's bundle size and improve performance.

// To enable Hermes, modify the `android/app/build.gradle` file as follows:
// 1. In `project.ext.react`, set `enableHermes: true`.
// 2. Rebuild the app to generate a smaller bundle size.
project.ext.react = [
  enableHermes: true,  // Enable Hermes
  // other settings
];
// Rebuild the app for the changes to take effect.
            

5. Using shouldComponentUpdate for Performance Optimization

This example demonstrates how to implement `shouldComponentUpdate` lifecycle method in class components to prevent re-renders when unnecessary.

// Implementing shouldComponentUpdate to prevent re-renders:
class MyComponent extends React.Component {
  shouldComponentUpdate(nextProps, nextState) {
    // Only re-render if the 'name' prop changes
    return nextProps.name !== this.props.name;
  }

  render() {
    console.log('Rendering MyComponent');
    return 

{this.props.name}

; } }

Building Custom Components and Libraries

Custom components and libraries allow you to create reusable UI elements and share them across projects.

Topics covered:

  • Creating reusable UI components
  • Publishing a custom React Native library
  • Styling components with styled-components
  • Handling accessibility in custom components

Examples

1. Building a Reusable Button Component

This example demonstrates how to create a custom button component that can be reused throughout your app.

// Reusable Button Component
import React from 'react';
import { TouchableOpacity, Text, StyleSheet } from 'react-native';

const MyButton = ({ title, onPress }) => {
  return (
    
      {title}
    
  );
};

const styles = StyleSheet.create({
  button: {
    backgroundColor: '#4CAF50',
    padding: 10,
    borderRadius: 5,
    alignItems: 'center',
  },
  text: {
    color: 'white',
    fontSize: 16,
  },
});

export default MyButton;
            

2. Creating a Custom Slider Component

This example shows how to build a custom slider component with customizable properties like min, max, and step values.

// Custom Slider Component
import React from 'react';
import { Slider, View, Text } from 'react-native';

const MySlider = ({ min, max, step, value, onValueChange }) => {
  return (
    
      Slider Value: {value}
      
    
  );
};

export default MySlider;
            

3. Publishing a Library to npm

This example demonstrates how to package your custom components into a library and publish it to npm for sharing.

// Step 1: Initialize a new npm package
// Run `npm init` to create a package.json file
// Step 2: Add your custom components to the library
// Example: Save your custom components in a 'src' folder
// Step 3: Publish to npm
// Run `npm publish` to publish the package to npm

// Example of package.json
{
  "name": "my-react-native-library",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "jest"
  },
  "dependencies": {
    "react-native": "^0.64.0"
  }
}
            

4. Using Styled-Components for Styling

This example shows how to style your components using `styled-components` to keep the styles modular and reusable.

// Using styled-components for styling a button
import React from 'react';
import styled from 'styled-components/native';

const Button = styled.TouchableOpacity`
  background-color: #4CAF50;
  padding: 10px;
  border-radius: 5px;
  align-items: center;
`;

const ButtonText = styled.Text`
  color: white;
  font-size: 16px;
`;

const MyStyledButton = ({ title, onPress }) => {
  return (
    
  );
};

export default MyStyledButton;
            

5. Implementing Accessibility Features in Custom Components

This example demonstrates how to add accessibility properties to custom components to make them usable by people with disabilities.

// Adding accessibility props to a button component
import React from 'react';
import { TouchableOpacity, Text } from 'react-native';

const AccessibleButton = ({ title, onPress }) => {
  return (
    
      {title}
    
  );
};

export default AccessibleButton;