Author: saqibkhan

  • Advanced Search and Filters

    To improve the search functionality, we can add multiple filters such as category, completion status, and keyword search.

    Implementing Advanced Search

    1. Define Filter States:
    javascriptCopy codeconst [completionFilter, setCompletionFilter] = useState('all');
    
    1. Update the Filter Logic:

    When filtering items, check against multiple criteria:

    javascriptCopy codeconst filteredItems = items.filter(item => {
      const matchesCompletion = completionFilter === 'all' || (completionFilter === 'completed' && item.completed) || (completionFilter === 'uncompleted' && !item.completed);
      const matchesCategory = item.category === selectedCategory || selectedCategory === 'all';
      const matchesSearch = item.text.toLowerCase().includes(searchQuery.toLowerCase());
      return matchesCompletion && matchesCategory && matchesSearch;
    });
    
    1. Add UI Elements for Filters:

    Include dropdowns or pickers for completion status and categories, allowing users to select their filters:

    javascriptCopy code<Picker
      selectedValue={completionFilter}
      onValueChange={(itemValue) => setCompletionFilter(itemValue)}
    >
      <Picker.Item label="All" value="all" />
      <Picker.Item label="Completed" value="completed" />
      <Picker.Item label="Uncompleted" value="uncompleted" />
    </Picker>
    

    Step 2: Offline Support

    To implement offline support, you can use libraries like @react-native-async-storage/async-storage or even better, use Firestore’s built-in offline capabilities.

    Enable Firestore Offline Persistence

    1. Enable Persistence:

    In your firebaseConfig.js, enable persistence like this:

    javascriptCopy codeimport { enablePersistence } from 'firebase/firestore';
    
    enablePersistence(db)
      .catch((err) => {
    
    if (err.code === 'failed-precondition') {
      // Multiple tabs open, persistence can only be enabled in one tab at a time.
    } else if (err.code === 'unimplemented') {
      // The current browser does not support all of the features required to enable persistence
    }
    });
    1. Sync Data:

    When users are offline, the app can still function normally, and Firestore will sync data when the user is back online.

    Step 3: User Preferences

    Allow users to customize their experience by adding a settings screen where they can adjust preferences like theme and default filters.

    Implementing User Preferences

    1. Create a Settings Screen:

    You can create a new component for settings:

    javascriptCopy codeconst Settings = ({ navigation }) => {
      const [theme, setTheme] = useState('light');
    
      const savePreferences = async () => {
    
    await AsyncStorage.setItem('userTheme', theme);
    }; useEffect(() => {
    const loadPreferences = async () =&gt; {
      const storedTheme = await AsyncStorage.getItem('userTheme');
      if (storedTheme) {
        setTheme(storedTheme);
      }
    };
    loadPreferences();
    }, []); return (
    &lt;View&gt;
      &lt;Text&gt;Choose Theme:&lt;/Text&gt;
      &lt;Picker
        selectedValue={theme}
        onValueChange={(itemValue) =&gt; setTheme(itemValue)}
      &gt;
        &lt;Picker.Item label="Light" value="light" /&gt;
        &lt;Picker.Item label="Dark" value="dark" /&gt;
      &lt;/Picker&gt;
      &lt;Button onPress={savePreferences}&gt;Save Preferences&lt;/Button&gt;
    &lt;/View&gt;
    ); };
    1. Navigation:

    Add a button in your main app to navigate to the Settings screen.

    Step 4: Analytics Dashboard

    Provide users with insights into their item lists, such as completion rates, item categories, and trends over time.

    Implementing Analytics

    1. Calculate Metrics:

    Create functions to calculate metrics based on user data:

    javascriptCopy codeconst getCompletionRate = () => {
      const completedItems = items.filter(item => item.completed).length;
      return (completedItems / items.length) * 100;
    };
    
    const getCategoryCounts = () => {
      return items.reduce((acc, item) => {
    
    acc&#91;item.category] = (acc&#91;item.category] || 0) + 1;
    return acc;
    }, {}); };
    1. Display Analytics:

    Create a new component to show these metrics:

    javascriptCopy codeconst Analytics = () => {
      const completionRate = getCompletionRate();
      const categoryCounts = getCategoryCounts();
    
      return (
    
    &lt;View&gt;
      &lt;Text&gt;Completion Rate: {completionRate}%&lt;/Text&gt;
      &lt;Text&gt;Category Breakdown:&lt;/Text&gt;
      {Object.entries(categoryCounts).map((&#91;category, count]) =&gt; (
        &lt;Text key={category}&gt;{${category}: ${count}}&lt;/Text&gt;
      ))}
    &lt;/View&gt;
    ); };
  • Item Reminders

    To implement item reminders, we can use a combination of local notifications and a date picker.

    Install Dependencies

    You’ll need to install @react-native-community/datetimepicker for date selection and react-native-push-notification for local notifications.

    bashCopy codenpm install @react-native-community/datetimepicker react-native-push-notification
    

    Configure Local Notifications

    You need to configure notifications for your app. Here’s a basic setup:

    javascriptCopy code// notificationConfig.js
    import PushNotification from 'react-native-push-notification';
    
    PushNotification.configure({
      onNotification: function(notification) {
    
    console.log("NOTIFICATION:", notification);
    }, // Other configurations can be added here });

    Call this configuration in your App.js file:

    javascriptCopy codeimport './notificationConfig';
    

    Add Reminder Functionality

    Update your App.js to include a date picker for setting reminders:

    javascriptCopy codeimport DateTimePicker from '@react-native-community/datetimepicker';
    
    // State to manage reminder
    const [reminderDate, setReminderDate] = useState(new Date());
    const [showDatePicker, setShowDatePicker] = useState(false);
    
    // Function to handle date change
    const onDateChange = (event, selectedDate) => {
      const currentDate = selectedDate || reminderDate;
      setShowDatePicker(false);
      setReminderDate(currentDate);
    };
    
    // Function to schedule the notification
    const scheduleNotification = (item) => {
      PushNotification.localNotificationSchedule({
    
    message: item.text,
    date: reminderDate,
    }); }; // When adding an item const addItem = async () => { if (textInput.trim() && user) {
    const newItem = { text: textInput, completed: false, reminder: reminderDate };
    const docRef = await addDoc(collection(db, user.uid), newItem);
    setItems(&#91;...items, { key: docRef.id, ...newItem }]);
    scheduleNotification(newItem);
    setTextInput('');
    } }; // Render date picker {showDatePicker && ( <DateTimePicker
    value={reminderDate}
    mode="date"
    display="default"
    onChange={onDateChange}
    /> )}
  • Set Up Firebase

    First, we need to set up Firebase for our project. If you haven’t already:

    1. Go to the Firebase Console.
    2. Create a new project.
    3. Enable Firestore and Authentication (Email/Password method).
    4. Add your app (iOS/Android) and follow the instructions to set it up.

    Install Firebase SDK

    In your project directory, install the Firebase SDK:

    bashCopy codenpm install firebase
    

    Step 2: Set Up Firebase Configuration

    Create a new file called firebaseConfig.js in your project directory and add your Firebase configuration:

    javascriptCopy code// firebaseConfig.js
    import { initializeApp } from 'firebase/app';
    import { getFirestore } from 'firebase/firestore';
    import { getAuth } from 'firebase/auth';
    
    const firebaseConfig = {
      apiKey: "YOUR_API_KEY",
      authDomain: "YOUR_AUTH_DOMAIN",
      projectId: "YOUR_PROJECT_ID",
      storageBucket: "YOUR_STORAGE_BUCKET",
      messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
      appId: "YOUR_APP_ID",
    };
    
    // Initialize Firebase
    const app = initializeApp(firebaseConfig);
    const db = getFirestore(app);
    const auth = getAuth(app);
    
    export { db, auth };
    

    Make sure to replace the placeholder values with your actual Firebase project details.

    Step 3: User Authentication

    Add Authentication Functions

    Update App.js to include authentication functions:

    javascriptCopy codeimport React, { useEffect, useState } from 'react';
    import { StyleSheet, View, FlatList, Alert } from 'react-native';
    import { Provider as PaperProvider, TextInput, Button, List, Appbar } from 'react-native-paper';
    import { db, auth } from './firebaseConfig'; // Import Firebase
    import { signInWithEmailAndPassword, createUserWithEmailAndPassword } from 'firebase/auth';
    import { collection, addDoc, getDocs } from 'firebase/firestore';
    
    const App = () => {
      const [items, setItems] = useState([]);
      const [textInput, setTextInput] = useState('');
      const [editIndex, setEditIndex] = useState(null);
      const [email, setEmail] = useState('');
      const [password, setPassword] = useState('');
      const [user, setUser] = useState(null);
    
      useEffect(() => {
    
    const unsubscribe = auth.onAuthStateChanged(currentUser =&gt; {
      setUser(currentUser);
      if (currentUser) {
        loadItems(currentUser.uid);
      }
    });
    return () =&gt; unsubscribe();
    }, []); const loadItems = async (userId) => {
    const querySnapshot = await getDocs(collection(db, userId));
    const loadedItems = querySnapshot.docs.map(doc =&gt; ({ key: doc.id, ...doc.data() }));
    setItems(loadedItems);
    }; const addItem = async () => {
    if (textInput.trim() &amp;&amp; user) {
      const newItem = { text: textInput, completed: false };
      const docRef = await addDoc(collection(db, user.uid), newItem);
      setItems(&#91;...items, { key: docRef.id, ...newItem }]);
      setTextInput('');
    }
    }; const register = async () => {
    try {
      await createUserWithEmailAndPassword(auth, email, password);
      setEmail('');
      setPassword('');
    } catch (error) {
      console.error(error);
    }
    }; const login = async () => {
    try {
      await signInWithEmailAndPassword(auth, email, password);
      setEmail('');
      setPassword('');
    } catch (error) {
      console.error(error);
    }
    }; return (
    &lt;PaperProvider&gt;
      &lt;Appbar.Header&gt;
        &lt;Appbar.Content title="My Item List" /&gt;
      &lt;/Appbar.Header&gt;
      &lt;View style={styles.container}&gt;
        {user ? (
          &lt;&gt;
            &lt;TextInput
              label="Add or edit an item"
              value={textInput}
              onChangeText={setTextInput}
              style={styles.input}
            /&gt;
            &lt;Button mode="contained" onPress={addItem}&gt;Add Item&lt;/Button&gt;
            &lt;FlatList
              data={items}
              renderItem={({ item }) =&gt; (
                &lt;List.Item
                  title={item.text}
                  onPress={() =&gt; toggleCompletion(item)}
                  right={props =&gt; (
                    &lt;Button onPress={() =&gt; startEditing(item)}&gt;Edit&lt;/Button&gt;
                  )}
                  onLongPress={() =&gt; confirmDelete(item)}
                /&gt;
              )}
              keyExtractor={(item) =&gt; item.key}
            /&gt;
          &lt;/&gt;
        ) : (
          &lt;&gt;
            &lt;TextInput label="Email" value={email} onChangeText={setEmail} /&gt;
            &lt;TextInput label="Password" value={password} secureTextEntry onChangeText={setPassword} /&gt;
            &lt;Button mode="contained" onPress={register}&gt;Register&lt;/Button&gt;
            &lt;Button mode="outlined" onPress={login}&gt;Login&lt;/Button&gt;
          &lt;/&gt;
        )}
      &lt;/View&gt;
    &lt;/PaperProvider&gt;
    ); }; const styles = StyleSheet.create({ container: {
    flex: 1,
    padding: 20,
    backgroundColor: '#fff',
    }, input: {
    marginBottom: 10,
    }, }); export default App;
  • Update the App to Use React Native Paper

    First, let’s integrate React Native Paper components into our app.

    Install Dependencies

    If you haven’t already, ensure you have the dependencies installed:

    bashCopy codenpm install react-native-paper
    

    You’ll also need to set up react-native-vector-icons for icons used in React Native Paper:

    bashCopy codenpm install react-native-vector-icons
    

    Update App.js

    Here’s an updated version of App.js that uses React Native Paper components:

    javascriptCopy codeimport React, { useEffect, useState } from 'react';
    import { StyleSheet, View, FlatList, Alert } from 'react-native';
    import { Provider as PaperProvider, TextInput, Button, List, Picker, Appbar } from 'react-native-paper';
    import AsyncStorage from '@react-native-async-storage/async-storage';
    
    const App = () => {
      const [items, setItems] = useState([]);
      const [textInput, setTextInput] = useState('');
      const [editIndex, setEditIndex] = useState(null);
      const [filter, setFilter] = useState('all');
      const [searchQuery, setSearchQuery] = useState('');
    
      useEffect(() => {
    
    const loadItems = async () =&gt; {
      try {
        const storedItems = await AsyncStorage.getItem('items');
        if (storedItems) {
          setItems(JSON.parse(storedItems));
        }
      } catch (error) {
        console.error(error);
      }
    };
    loadItems();
    }, []); useEffect(() => {
    const saveItems = async () =&gt; {
      try {
        await AsyncStorage.setItem('items', JSON.stringify(items));
      } catch (error) {
        console.error(error);
      }
    };
    saveItems();
    }, [items]); const addItem = () => {
    if (textInput.trim()) {
      const newItem = { key: textInput, completed: false };
      if (editIndex !== null) {
        const updatedItems = items.map((item, index) =&gt;
          index === editIndex ? newItem : item
        );
        setItems(updatedItems);
        setEditIndex(null);
      } else {
        setItems(&#91;...items, newItem]);
      }
      setTextInput('');
    }
    }; const deleteItem = (itemToDelete) => {
    setItems(items.filter(item =&gt; item.key !== itemToDelete));
    }; const confirmDelete = (item) => {
    Alert.alert(
      'Delete Item',
      Are you sure you want to delete "${item.key}"?,
      &#91;
        { text: 'Cancel', style: 'cancel' },
        { text: 'OK', onPress: () =&gt; deleteItem(item.key) },
      ],
      { cancelable: true }
    );
    }; const toggleCompletion = (item) => {
    const updatedItems = items.map(i =&gt;
      i.key === item.key ? { ...i, completed: !i.completed } : i
    );
    setItems(updatedItems);
    }; const startEditing = (item, index) => {
    setTextInput(item.key);
    setEditIndex(index);
    }; // Filtering items based on the selected filter const filteredItems = items.filter(item => {
    const matchesFilter = (filter === 'all' || (filter === 'completed' &amp;&amp; item.completed) || (filter === 'uncompleted' &amp;&amp; !item.completed));
    const matchesSearch = item.key.toLowerCase().includes(searchQuery.toLowerCase());
    return matchesFilter &amp;&amp; matchesSearch;
    }); return (
    &lt;PaperProvider&gt;
      &lt;Appbar.Header&gt;
        &lt;Appbar.Content title="My Item List" /&gt;
      &lt;/Appbar.Header&gt;
      &lt;View style={styles.container}&gt;
        &lt;TextInput
          label="Add or edit an item"
          value={textInput}
          onChangeText={setTextInput}
          style={styles.input}
        /&gt;
        &lt;Button mode="contained" onPress={addItem}&gt;
          {editIndex !== null ? "Update Item" : "Add Item"}
        &lt;/Button&gt;
        &lt;TextInput
          label="Search items"
          value={searchQuery}
          onChangeText={setSearchQuery}
          style={styles.input}
        /&gt;
        &lt;Picker
          selectedValue={filter}
          style={styles.picker}
          onValueChange={(itemValue) =&gt; setFilter(itemValue)}
        &gt;
          &lt;Picker.Item label="All" value="all" /&gt;
          &lt;Picker.Item label="Completed" value="completed" /&gt;
          &lt;Picker.Item label="Uncompleted" value="uncompleted" /&gt;
        &lt;/Picker&gt;
        &lt;FlatList
          data={filteredItems}
          renderItem={({ item }) =&gt; (
            &lt;List.Item
              title={item.key}
              onPress={() =&gt; toggleCompletion(item)}
              right={props =&gt; (
                &lt;Button onPress={() =&gt; startEditing(item)}&gt;Edit&lt;/Button&gt;
              )}
              onLongPress={() =&gt; confirmDelete(item)}
              style={&#91;styles.item, item.completed &amp;&amp; styles.completedItem]}
            /&gt;
          )}
          keyExtractor={(item) =&gt; item.key}
        /&gt;
      &lt;/View&gt;
    &lt;/PaperProvider&gt;
    ); }; const styles = StyleSheet.create({ container: {
    flex: 1,
    padding: 20,
    backgroundColor: '#fff',
    }, input: {
    marginBottom: 10,
    }, picker: {
    height: 50,
    width: 150,
    marginBottom: 10,
    }, item: {
    padding: 10,
    }, completedItem: {
    textDecorationLine: 'line-through',
    color: 'gray',
    }, }); export default App;
  • Implement Filtering Functionality

    Let’s start by adding a filter feature. Here’s how you can modify your App.js to include filtering options.

    Updated Code for App.js

    javascriptCopy codeimport React, { useEffect, useState } from 'react';
    import { StyleSheet, Text, View, FlatList, TextInput, Button, TouchableOpacity, Alert, Picker } from 'react-native';
    import AsyncStorage from '@react-native-async-storage/async-storage';
    
    const App = () => {
      const [items, setItems] = useState([]);
      const [textInput, setTextInput] = useState('');
      const [editIndex, setEditIndex] = useState(null);
      const [filter, setFilter] = useState('all');
    
      useEffect(() => {
    
    const loadItems = async () =&gt; {
      try {
        const storedItems = await AsyncStorage.getItem('items');
        if (storedItems) {
          setItems(JSON.parse(storedItems));
        }
      } catch (error) {
        console.error(error);
      }
    };
    loadItems();
    }, []); useEffect(() => {
    const saveItems = async () =&gt; {
      try {
        await AsyncStorage.setItem('items', JSON.stringify(items));
      } catch (error) {
        console.error(error);
      }
    };
    saveItems();
    }, [items]); const addItem = () => {
    if (textInput.trim()) {
      const newItem = { key: textInput, completed: false };
      if (editIndex !== null) {
        const updatedItems = items.map((item, index) =&gt;
          index === editIndex ? newItem : item
        );
        setItems(updatedItems);
        setEditIndex(null);
      } else {
        setItems(&#91;...items, newItem]);
      }
      setTextInput('');
    }
    }; const deleteItem = (itemToDelete) => {
    setItems(items.filter(item =&gt; item.key !== itemToDelete));
    }; const confirmDelete = (item) => {
    Alert.alert(
      'Delete Item',
      Are you sure you want to delete "${item.key}"?,
      &#91;
        { text: 'Cancel', style: 'cancel' },
        { text: 'OK', onPress: () =&gt; deleteItem(item.key) },
      ],
      { cancelable: true }
    );
    }; const toggleCompletion = (item) => {
    const updatedItems = items.map(i =&gt;
      i.key === item.key ? { ...i, completed: !i.completed } : i
    );
    setItems(updatedItems);
    }; const startEditing = (item, index) => {
    setTextInput(item.key);
    setEditIndex(index);
    }; // Filtering items based on the selected filter const filteredItems = items.filter(item => {
    if (filter === 'completed') return item.completed;
    if (filter === 'uncompleted') return !item.completed;
    return true; // 'all'
    }); return (
    &lt;View style={styles.container}&gt;
      &lt;Text style={styles.title}&gt;My Item List&lt;/Text&gt;
      &lt;TextInput
        style={styles.input}
        placeholder="Add or edit an item"
        value={textInput}
        onChangeText={setTextInput}
      /&gt;
      &lt;Button title={editIndex !== null ? "Update Item" : "Add Item"} onPress={addItem} /&gt;
      
      {/* Filter Picker */}
      &lt;Picker
        selectedValue={filter}
        style={styles.picker}
        onValueChange={(itemValue) =&gt; setFilter(itemValue)}
      &gt;
        &lt;Picker.Item label="All" value="all" /&gt;
        &lt;Picker.Item label="Completed" value="completed" /&gt;
        &lt;Picker.Item label="Uncompleted" value="uncompleted" /&gt;
      &lt;/Picker&gt;
      &lt;FlatList
        data={filteredItems}
        renderItem={({ item, index }) =&gt; (
          &lt;TouchableOpacity onLongPress={() =&gt; confirmDelete(item)} onPress={() =&gt; toggleCompletion(item)}&gt;
            &lt;Text style={&#91;styles.item, item.completed &amp;&amp; styles.completedItem]}&gt;
              {item.key}
            &lt;/Text&gt;
            &lt;Button title="Edit" onPress={() =&gt; startEditing(item, index)} /&gt;
          &lt;/TouchableOpacity&gt;
        )}
        keyExtractor={(item) =&gt; item.key}
      /&gt;
    &lt;/View&gt;
    ); }; const styles = StyleSheet.create({ container: {
    flex: 1,
    padding: 20,
    backgroundColor: '#fff',
    }, title: {
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 20,
    }, input: {
    height: 40,
    borderColor: 'gray',
    borderWidth: 1,
    marginBottom: 10,
    paddingHorizontal: 10,
    }, picker: {
    height: 50,
    width: 150,
    marginBottom: 10,
    }, item: {
    padding: 10,
    fontSize: 18,
    borderBottomColor: '#ccc',
    borderBottomWidth: 1,
    }, completedItem: {
    textDecorationLine: 'line-through',
    color: 'gray',
    }, }); export default App;
  • Update the Item Structure

    First, modify the way items are structured to include a completed state. We’ll adjust the addItem, deleteItem, and other relevant functions accordingly.

    Updated Code for App.js

    Here’s the updated code:

    javascriptCopy codeimport React, { useEffect, useState } from 'react';
    import { StyleSheet, Text, View, FlatList, TextInput, Button, TouchableOpacity, Alert } from 'react-native';
    import AsyncStorage from '@react-native-async-storage/async-storage';
    
    const App = () => {
      const [items, setItems] = useState([]);
      const [textInput, setTextInput] = useState('');
      const [editIndex, setEditIndex] = useState(null);
    
      useEffect(() => {
    
    const loadItems = async () =&gt; {
      try {
        const storedItems = await AsyncStorage.getItem('items');
        if (storedItems) {
          setItems(JSON.parse(storedItems));
        }
      } catch (error) {
        console.error(error);
      }
    };
    loadItems();
    }, []); useEffect(() => {
    const saveItems = async () =&gt; {
      try {
        await AsyncStorage.setItem('items', JSON.stringify(items));
      } catch (error) {
        console.error(error);
      }
    };
    saveItems();
    }, [items]); const addItem = () => {
    if (textInput.trim()) {
      const newItem = { key: textInput, completed: false };
      if (editIndex !== null) {
        const updatedItems = items.map((item, index) =&gt;
          index === editIndex ? newItem : item
        );
        setItems(updatedItems);
        setEditIndex(null);
      } else {
        setItems(&#91;...items, newItem]);
      }
      setTextInput('');
    }
    }; const deleteItem = (itemToDelete) => {
    setItems(items.filter(item =&gt; item.key !== itemToDelete));
    }; const confirmDelete = (item) => {
    Alert.alert(
      'Delete Item',
      Are you sure you want to delete "${item.key}"?,
      &#91;
        { text: 'Cancel', style: 'cancel' },
        { text: 'OK', onPress: () =&gt; deleteItem(item.key) },
      ],
      { cancelable: true }
    );
    }; const toggleCompletion = (item) => {
    const updatedItems = items.map(i =&gt;
      i.key === item.key ? { ...i, completed: !i.completed } : i
    );
    setItems(updatedItems);
    }; const startEditing = (item, index) => {
    setTextInput(item.key);
    setEditIndex(index);
    }; return (
    &lt;View style={styles.container}&gt;
      &lt;Text style={styles.title}&gt;My Item List&lt;/Text&gt;
      &lt;TextInput
        style={styles.input}
        placeholder="Add or edit an item"
        value={textInput}
        onChangeText={setTextInput}
      /&gt;
      &lt;Button title={editIndex !== null ? "Update Item" : "Add Item"} onPress={addItem} /&gt;
      &lt;FlatList
        data={items}
        renderItem={({ item, index }) =&gt; (
          &lt;TouchableOpacity onLongPress={() =&gt; confirmDelete(item)} onPress={() =&gt; toggleCompletion(item)}&gt;
            &lt;Text style={&#91;styles.item, item.completed &amp;&amp; styles.completedItem]}&gt;
              {item.key}
            &lt;/Text&gt;
            &lt;Button title="Edit" onPress={() =&gt; startEditing(item, index)} /&gt;
          &lt;/TouchableOpacity&gt;
        )}
        keyExtractor={(item) =&gt; item.key}
      /&gt;
    &lt;/View&gt;
    ); }; const styles = StyleSheet.create({ container: {
    flex: 1,
    padding: 20,
    backgroundColor: '#fff',
    }, title: {
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 20,
    }, input: {
    height: 40,
    borderColor: 'gray',
    borderWidth: 1,
    marginBottom: 10,
    paddingHorizontal: 10,
    }, item: {
    padding: 10,
    fontSize: 18,
    borderBottomColor: '#ccc',
    borderBottomWidth: 1,
    }, completedItem: {
    textDecorationLine: 'line-through',
    color: 'gray',
    }, }); export default App;
  • Install AsyncStorage

    You need to install the @react-native-async-storage/async-storage package. Run the following command in your project directory:

    bashCopy codenpm install @react-native-async-storage/async-storage
    

    Step 2: Update App.js

    Replace the existing code in App.js with the following code:

    javascriptCopy codeimport React, { useEffect, useState } from 'react';
    import { StyleSheet, Text, View, FlatList, TextInput, Button, TouchableOpacity, Alert } from 'react-native';
    import AsyncStorage from '@react-native-async-storage/async-storage';
    
    const App = () => {
      const [items, setItems] = useState([]);
      const [textInput, setTextInput] = useState('');
    
      // Load items from AsyncStorage on app start
      useEffect(() => {
    
    const loadItems = async () =&gt; {
      try {
        const storedItems = await AsyncStorage.getItem('items');
        if (storedItems) {
          setItems(JSON.parse(storedItems));
        }
      } catch (error) {
        console.error(error);
      }
    };
    loadItems();
    }, []); // Save items to AsyncStorage whenever they change useEffect(() => {
    const saveItems = async () =&gt; {
      try {
        await AsyncStorage.setItem('items', JSON.stringify(items));
      } catch (error) {
        console.error(error);
      }
    };
    saveItems();
    }, [items]); const addItem = () => {
    if (textInput.trim()) {
      setItems(&#91;...items, { key: textInput }]);
      setTextInput('');
    }
    }; const deleteItem = (itemToDelete) => {
    setItems(items.filter(item =&gt; item.key !== itemToDelete));
    }; const confirmDelete = (item) => {
    Alert.alert(
      'Delete Item',
      Are you sure you want to delete "${item.key}"?,
      &#91;
        { text: 'Cancel', style: 'cancel' },
        { text: 'OK', onPress: () =&gt; deleteItem(item.key) },
      ],
      { cancelable: true }
    );
    }; return (
    &lt;View style={styles.container}&gt;
      &lt;Text style={styles.title}&gt;My Item List&lt;/Text&gt;
      &lt;TextInput
        style={styles.input}
        placeholder="Add a new item"
        value={textInput}
        onChangeText={setTextInput}
      /&gt;
      &lt;Button title="Add Item" onPress={addItem} /&gt;
      &lt;FlatList
        data={items}
        renderItem={({ item }) =&gt; (
          &lt;TouchableOpacity onLongPress={() =&gt; confirmDelete(item)}&gt;
            &lt;Text style={styles.item}&gt;{item.key}&lt;/Text&gt;
          &lt;/TouchableOpacity&gt;
        )}
        keyExtractor={(item) =&gt; item.key}
      /&gt;
    &lt;/View&gt;
    ); }; const styles = StyleSheet.create({ container: {
    flex: 1,
    padding: 20,
    backgroundColor: '#fff',
    }, title: {
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 20,
    }, input: {
    height: 40,
    borderColor: 'gray',
    borderWidth: 1,
    marginBottom: 10,
    paddingHorizontal: 10,
    }, item: {
    padding: 10,
    fontSize: 18,
    borderBottomColor: '#ccc',
    borderBottomWidth: 1,
    }, }); export default App;
  • Set Up Your Project

    First, make sure you have React Native set up. If you haven’t set up a project yet, you can create one using the following command:

    bashCopy codenpx react-native init MyAwesomeApp
    

    Step 2: Create a Simple List App

    Now, you can replace the contents of App.js with the following code:

    javascriptCopy codeimport React, { useState } from 'react';
    import { StyleSheet, Text, View, FlatList, TextInput, Button } from 'react-native';
    
    const App = () => {
      const [items, setItems] = useState([]);
      const [textInput, setTextInput] = useState('');
    
      const addItem = () => {
    
    if (textInput.trim()) {
      setItems(&#91;...items, { key: textInput }]);
      setTextInput('');
    }
    }; return (
    &lt;View style={styles.container}&gt;
      &lt;Text style={styles.title}&gt;My Item List&lt;/Text&gt;
      &lt;TextInput
        style={styles.input}
        placeholder="Add a new item"
        value={textInput}
        onChangeText={setTextInput}
      /&gt;
      &lt;Button title="Add Item" onPress={addItem} /&gt;
      &lt;FlatList
        data={items}
        renderItem={({ item }) =&gt; &lt;Text style={styles.item}&gt;{item.key}&lt;/Text&gt;}
        keyExtractor={(item) =&gt; item.key}
      /&gt;
    &lt;/View&gt;
    ); }; const styles = StyleSheet.create({ container: {
    flex: 1,
    padding: 20,
    backgroundColor: '#fff',
    }, title: {
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 20,
    }, input: {
    height: 40,
    borderColor: 'gray',
    borderWidth: 1,
    marginBottom: 10,
    paddingHorizontal: 10,
    }, item: {
    padding: 10,
    fontSize: 18,
    borderBottomColor: '#ccc',
    borderBottomWidth: 1,
    }, }); export default App;

    Step 3: Run Your App

    To run your app, use the following command in your project directory:

    bashCopy codenpx react-native run-android
    

    or

    bashCopy codenpx react-native run-ios
  • Remoteok Blog

    • This blog features articles on remote work and development, including content focused on React Native. It’s useful for developers looking to work remotely while honing their skills.
    • Remoteok Blog
  • React Native Training

    • This site offers detailed articles, courses, and tutorials for learning React Native, including practical examples and best practices.
    • React Native Training