Getting Started

React Native Setup

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

# Create a new React Native project
npx react-native init MyProject

# Or create a project with TypeScript
npx react-native init MyProject --template react-native-template-typescript

# Run on Android
npx react-native run-android

# Run on iOS
npx react-native run-ios

# Using Expo CLI
npm install -g expo-cli
expo init MyProject
expo start
Note: For React Native CLI, you need Android Studio and Xcode installed. Expo provides a simpler setup but with some limitations.

Basic App Structure

// App.js - Basic React Native App
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

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

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  text: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
});

export default App;

// index.js - Entry point
import { AppRegistry } from 'react-native';
import App from './App';
import { name as appName } from './app.json';

AppRegistry.registerComponent(appName, () => App);

Core Components

Basic Components

// View - Container component
<View
  style={{
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#fff'
  }}
>
  <!-- Content here -->
</View>

// Text - Display text
<Text
  style={{
    fontSize: 18,
    fontWeight: 'bold',
    color: '#333'
  }}
  numberOfLines={1}
>
  Hello World!
</Text>

// Image - Display images
<Image
  source={{ uri: 'https://example.com/image.jpg' }}
  style={{ width: 200, height: 200 }}
  resizeMode="cover"
/>

// Local image
<Image
  source={require('./assets/image.png')}
  style={{ width: 200, height: 200 }}
/>
Note: View is similar to div in HTML, Text must be used for all text, and Image requires explicit dimensions.

Interactive Components

// Button
<Button
  title="Press Me"
  onPress={() => alert('Button pressed!')}
  color="#841584"
/>

// Touchable Components
<TouchableOpacity
  onPress={() => alert('Pressed with opacity effect')}
  style={{ padding: 10, backgroundColor: '#ddd' }}
>
  <Text>Press Me</Text>
</TouchableOpacity>

<TouchableHighlight
  onPress={() => alert('Pressed with highlight effect')}
  underlayColor="white"
>
  <View style={{ padding: 10 }}>
    <Text>Press Me</Text>
  </View>
</TouchableHighlight>

// TextInput
<TextInput
  style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
  onChangeText={(text) => setText(text)}
  value={text}
  placeholder="Enter text here"
  keyboardType="default"
/>

// Switch
<Switch
  value={isEnabled}
  onValueChange={setIsEnabled}
  trackColor={{ false: '#767577', true: '#81b0ff' }}
/>
Note: Button has limited styling options. For custom buttons, use TouchableOpacity or TouchableHighlight with custom styling.

List Components

// FlatList - for simple lists
<FlatList
  data={[
    { id: '1', title: 'Item 1' },
    { id: '2', title: 'Item 2' },
    { id: '3', title: 'Item 3' },
  ]}
  keyExtractor={(item) => item.id}
  renderItem={({ item }) => (
    <Text>{item.title}</Text>
  )}
/>

// SectionList - for sectioned lists
<SectionList
  sections={[
    {
      title: 'Section 1',
      data: ['Item 1', 'Item 2'],
    },
    {
      title: 'Section 2',
      data: ['Item 3', 'Item 4'],
    },
  ]}
  renderItem={({ item }) => <Text>{item}</Text>}
  renderSectionHeader={({ section }) => (
    <Text style={{ fontWeight: 'bold' }}>
      {section.title}
    </Text>
  )}
  keyExtractor={(item, index) => index.toString()}
/>

// ScrollView - for scrollable content
<ScrollView
  style={{ flex: 1 }}
  contentContainerStyle={{ padding: 20 }}
  showsVerticalScrollIndicator={false}
>
  <Text>Long content here...</Text>
</ScrollView>

Styling & Layout

// Flexbox layout example
<View style={{
  flex: 1,
  flexDirection: 'row', // or 'column'
  justifyContent: 'space-between', // or 'flex-start', 'center', 'flex-end', 'space-around', 'space-evenly'
  alignItems: 'center', // or 'flex-start', 'flex-end', 'stretch', 'baseline'
  backgroundColor: '#f0f0f0',
}}>
  <View style={{ width: 50, height: 50, backgroundColor: 'red' }} />
  <View style={{ width: 50, height: 50, backgroundColor: 'green' }} />
  <View style={{ width: 50, height: 50, backgroundColor: 'blue' }} />
</View>

// Using StyleSheet
const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
    backgroundColor: '#fff',
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 20,
    color: '#333',
  },
  button: {
    backgroundColor: '#007AFF',
    padding: 15,
    borderRadius: 5,
    alignItems: 'center',
  },
  buttonText: {
    color: '#fff',
    fontWeight: 'bold',
  },
});

// Platform-specific styles
const styles = StyleSheet.create({
  container: {
    flex: 1,
    ...Platform.select({
      ios: {
        backgroundColor: 'red',
      },
      android: {
        backgroundColor: 'blue',
      },
    }),
  },
});
Note: Flexbox is the primary layout system in React Native. StyleSheet.create provides performance optimizations and validation.

State Management

useState & useEffect

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

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

  return (
    <View>
      <Text>You clicked {count} times</Text>
      <Button
        title="Click me"
        onPress={() => setCount(count + 1)}
      />
    </View>
  );
};

// useEffect hook
import React, { useState, useEffect } from 'react';

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

  // Similar to componentDidMount and componentDidUpdate
  useEffect(() => {
    // Update the document title using the browser API
    document.title = `You clicked ${count} times`;
  });

  // Effect with cleanup (similar to componentWillUnmount)
  useEffect(() => {
    const subscription = API.subscribe();
    // Cleanup function
    return () => {
      subscription.unsubscribe();
    };
  }, []);

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

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

  if (loading) {
    return <Text>Loading...</Text>;
  }

  return (
    <View>
      {data.map(item => (
        <Text key={item.id}>{item.name}</Text>
      ))}
    </View>
  );
};

Context API & Redux

// Context API
import React, { createContext, useContext, useState } from 'react';

// Create a Context
const AuthContext = createContext();

// Create a provider component
export const AuthProvider = ({ children }) => {
  const [user, setUser] = useState(null);

  const login = (userData) => {
    setUser(userData);
  };

  const logout = () => {
    setUser(null);
  };

  return (
    <AuthContext.Provider value={{ user, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
};

// Custom hook to use the auth context
export const useAuth = () => {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error('useAuth must be used within an AuthProvider');
  }
  return context;
};

// Using the context in a component
const UserProfile = () => {
  const { user, logout } = useAuth();

  return (
    <View>
      <Text>Welcome {user?.name}</Text>
      <Button title="Logout" onPress={logout} />
    </View>
  );
};

// Redux Toolkit setup
import { configureStore, createSlice } from '@reduxjs/toolkit';

// Create a slice
const counterSlice = createSlice({
  name: 'counter',
  initialState: {
    value: 0,
  },
  reducers: {
    increment: (state) => {
      state.value += 1;
    },
    decrement: (state) => {
      state.value -= 1;
    },
    incrementByAmount: (state, action) => {
      state.value += action.payload;
    },
  },
});

// Export actions
export const { increment, decrement, incrementByAmount } = counterSlice.actions;

// Create store
const store = configureStore({
  reducer: {
    counter: counterSlice.reducer,
  },
});

// Using Redux in components with React-Redux hooks
import { useSelector, useDispatch } from 'react-redux';

const Counter = () => {
  const count = useSelector((state) => state.counter.value);
  const dispatch = useDispatch();

  return (
    <View>
      <Text>Count: {count}</Text>
      <Button title="Increment" onPress={() => dispatch(increment())} />
      <Button title="Decrement" onPress={() => dispatch(decrement())} />
    </View>
  );
};
Note: Use Context API for simple state that doesn't change often. For complex state management with frequent updates, use Redux Toolkit.