0
0
React Nativemobile~20 mins

SQLite with expo-sqlite in React Native - Mini App: Build & Ship

Choose your learning style9 modes available
Build: Notes List
A simple notes app screen that stores notes locally using SQLite with expo-sqlite. Users can add new notes and see the list of saved notes.
Target UI
-------------------------
| Notes List            |
|-----------------------|
| + Add Note            |
|-----------------------|
| - Note 1              |
| - Note 2              |
| - Note 3              |
|                       |
-------------------------
Use expo-sqlite to create a local database and a table for notes.
Display a list of notes stored in the database.
Add a button labeled '+ Add Note' that opens a prompt to enter a new note.
Save the new note to the database and update the list immediately.
Handle database opening, table creation, insertion, and querying.
Starter Code
React Native
import React, { useEffect, useState } from 'react';
import { View, Text, Button, FlatList, Alert, TextInput, Modal, StyleSheet } from 'react-native';
import * as SQLite from 'expo-sqlite';

const db = SQLite.openDatabase('notes.db');

export default function NotesList() {
  const [notes, setNotes] = useState([]);
  const [modalVisible, setModalVisible] = useState(false);
  const [newNote, setNewNote] = useState('');

  useEffect(() => {
    // TODO: Create notes table if not exists
    // TODO: Load notes from database
  }, []);

  const addNote = () => {
    // TODO: Insert newNote into database
    // TODO: Refresh notes list
    // TODO: Close modal and clear input
  };

  return (
    <View style={{ flex: 1, padding: 20 }}>
      <Button title='+ Add Note' onPress={() => setModalVisible(true)} />
      <FlatList
        data={notes}
        keyExtractor={(item) => item.id.toString()}
        renderItem={({ item }) => <Text style={{ padding: 10 }}>- {item.text}</Text>}
      />

      <Modal visible={modalVisible} animationType='slide' transparent={true}>
        <View style={styles.modalView}>
          <TextInput
            placeholder='Enter note'
            value={newNote}
            onChangeText={setNewNote}
            style={styles.input}
          />
          <Button title='Save' onPress={addNote} />
          <Button title='Cancel' onPress={() => setModalVisible(false)} />
        </View>
      </Modal>
    </View>
  );
}

const styles = StyleSheet.create({
  modalView: {
    margin: 20,
    backgroundColor: 'white',
    borderRadius: 8,
    padding: 20,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.25,
    shadowRadius: 4,
    elevation: 5,
    flex: 1,
    justifyContent: 'center'
  },
  input: {
    borderWidth: 1,
    borderColor: '#ccc',
    padding: 10,
    marginBottom: 10,
    borderRadius: 4
  }
});
Task 1
Task 2
Task 3
Solution
React Native
import React, { useEffect, useState } from 'react';
import { View, Text, Button, FlatList, TextInput, Modal, StyleSheet } from 'react-native';
import * as SQLite from 'expo-sqlite';

const db = SQLite.openDatabase('notes.db');

export default function NotesList() {
  const [notes, setNotes] = useState([]);
  const [modalVisible, setModalVisible] = useState(false);
  const [newNote, setNewNote] = useState('');

  useEffect(() => {
    db.transaction(tx => {
      tx.executeSql(
        'CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY AUTOINCREMENT, text TEXT);'
      );
    }, null, loadNotes);
  }, []);

  const loadNotes = () => {
    db.transaction(tx => {
      tx.executeSql(
        'SELECT * FROM notes;',
        [],
        (_, { rows }) => {
          setNotes(rows._array);
        }
      );
    });
  };

  const addNote = () => {
    if (newNote.trim() === '') return;
    db.transaction(tx => {
      tx.executeSql(
        'INSERT INTO notes (text) VALUES (?);',
        [newNote],
        () => {
          loadNotes();
          setModalVisible(false);
          setNewNote('');
        }
      );
    });
  };

  return (
    <View style={{ flex: 1, padding: 20 }}>
      <Button title='+ Add Note' onPress={() => setModalVisible(true)} />
      <FlatList
        data={notes}
        keyExtractor={(item) => item.id.toString()}
        renderItem={({ item }) => <Text style={{ padding: 10 }}>- {item.text}</Text>}
      />

      <Modal visible={modalVisible} animationType='slide' transparent={true}>
        <View style={styles.modalView}>
          <TextInput
            placeholder='Enter note'
            value={newNote}
            onChangeText={setNewNote}
            style={styles.input}
            accessibilityLabel='Note input field'
          />
          <Button title='Save' onPress={addNote} accessibilityLabel='Save note button' />
          <Button title='Cancel' onPress={() => setModalVisible(false)} accessibilityLabel='Cancel button' />
        </View>
      </Modal>
    </View>
  );
}

const styles = StyleSheet.create({
  modalView: {
    margin: 20,
    backgroundColor: 'white',
    borderRadius: 8,
    padding: 20,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.25,
    shadowRadius: 4,
    elevation: 5,
    flex: 1,
    justifyContent: 'center'
  },
  input: {
    borderWidth: 1,
    borderColor: '#ccc',
    padding: 10,
    marginBottom: 10,
    borderRadius: 4
  }
});

This app uses expo-sqlite to create a local database named notes.db. On first load, it creates a table called notes if it does not exist. Then it loads all saved notes into state and displays them in a list.

The '+ Add Note' button opens a modal with a text input. When the user types a note and taps 'Save', the note is inserted into the database. After insertion, the app reloads the notes list to show the new note immediately. The modal closes and the input clears.

Accessibility labels are added for better screen reader support. The UI uses simple components and styles for clarity and ease of use.

Final Result
Completed Screen
-------------------------
| Notes List            |
|-----------------------|
| + Add Note            |
|-----------------------|
| - Buy groceries       |
| - Call mom            |
| - Read a book         |
|                       |
-------------------------
User taps '+ Add Note' button to open a modal input.
User types a note and taps 'Save' to add it to the list.
The new note appears immediately in the list below.
User can tap 'Cancel' to close the modal without saving.
Stretch Goal
Add the ability to delete a note by tapping on it with a confirmation alert.
💡 Hint
Use a TouchableOpacity wrapping each note text. On press, show Alert.alert with Yes/No options. If Yes, delete the note from the database and reload the list.