0
0
React Nativemobile~20 mins

Why local data enables offline experience in React Native - Build It to Prove It

Choose your learning style9 modes available
Build: Offline Notes
This screen lets users write and save notes locally on their device so they can access them even without internet.
Target UI
-------------------------
|      Offline Notes     |
|-----------------------|
| [Type your note here] |
|                       |
| [Save Note]           |
|-----------------------|
| Saved Notes:          |
| - Note 1              |
| - Note 2              |
|                       |
-------------------------
A TextInput to type a note
A Save button to store the note locally
A list showing all saved notes
Notes persist and show even if app restarts or device is offline
Starter Code
React Native
import React, { useState, useEffect } from 'react';
import { View, Text, TextInput, Button, FlatList, StyleSheet } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';

export default function OfflineNotes() {
  const [note, setNote] = useState('');
  const [notes, setNotes] = useState([]);

  useEffect(() => {
    // TODO: Load saved notes from local storage here
  }, []);

  const saveNote = async () => {
    // TODO: Save the new note locally and update the list
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Offline Notes</Text>
      <TextInput
        style={styles.input}
        placeholder="Type your note here"
        value={note}
        onChangeText={setNote}
      />
      <Button title="Save Note" onPress={saveNote} />
      <Text style={styles.subtitle}>Saved Notes:</Text>
      <FlatList
        data={notes}
        keyExtractor={(item, index) => index.toString()}
        renderItem={({ item }) => <Text style={styles.noteItem}>- {item}</Text>}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, padding: 20, backgroundColor: '#fff' },
  title: { fontSize: 24, fontWeight: 'bold', marginBottom: 10 },
  input: { borderColor: '#ccc', borderWidth: 1, padding: 10, marginBottom: 10 },
  subtitle: { fontSize: 18, marginTop: 20, marginBottom: 10 },
  noteItem: { fontSize: 16, marginBottom: 5 }
});
Task 1
Task 2
Task 3
Solution
React Native
import React, { useState, useEffect } from 'react';
import { View, Text, TextInput, Button, FlatList, StyleSheet } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';

export default function OfflineNotes() {
  const [note, setNote] = useState('');
  const [notes, setNotes] = useState([]);

  useEffect(() => {
    const loadNotes = async () => {
      try {
        const savedNotes = await AsyncStorage.getItem('notes');
        if (savedNotes) {
          setNotes(JSON.parse(savedNotes));
        }
      } catch (e) {
        console.error('Failed to load notes.', e);
      }
    };
    loadNotes();
  }, []);

  const saveNote = async () => {
    if (note.trim() === '') return;
    const newNotes = [...notes, note.trim()];
    try {
      await AsyncStorage.setItem('notes', JSON.stringify(newNotes));
      setNotes(newNotes);
      setNote('');
    } catch (e) {
      console.error('Failed to save note.', e);
    }
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Offline Notes</Text>
      <TextInput
        style={styles.input}
        placeholder="Type your note here"
        value={note}
        onChangeText={setNote}
        accessibilityLabel="Note input field"
      />
      <Button title="Save Note" onPress={saveNote} accessibilityLabel="Save note button" />
      <Text style={styles.subtitle}>Saved Notes:</Text>
      <FlatList
        data={notes}
        keyExtractor={(item, index) => index.toString()}
        renderItem={({ item }) => <Text style={styles.noteItem}>- {item}</Text>}
        accessibilityLabel="List of saved notes"
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, padding: 20, backgroundColor: '#fff' },
  title: { fontSize: 24, fontWeight: 'bold', marginBottom: 10 },
  input: { borderColor: '#ccc', borderWidth: 1, padding: 10, marginBottom: 10, borderRadius: 4 },
  subtitle: { fontSize: 18, marginTop: 20, marginBottom: 10 },
  noteItem: { fontSize: 16, marginBottom: 5 }
});

This app uses AsyncStorage to save notes locally on the device. When the app starts, it loads any saved notes from local storage so the user can see them even without internet.

When the user types a note and taps Save, the note is added to the list and saved back to AsyncStorage. This means the data stays on the device and is available offline.

We use React Native's useEffect to load notes once on mount, and useState to manage the notes list and input. Accessibility labels help screen readers identify inputs and buttons.

This approach shows how local data storage enables offline experience by keeping user data on the device.

Final Result
Completed Screen
-------------------------
|      Offline Notes     |
|-----------------------|
| [Type your note here] |
|                       |
| [Save Note]           |
|-----------------------|
| Saved Notes:          |
| - Buy groceries       |
| - Call mom            |
|                       |
-------------------------
User types a note in the input field
User taps 'Save Note' button
Note appears in the saved notes list below
Notes remain visible after app restart or offline
Stretch Goal
Add a button to clear all saved notes from local storage
💡 Hint
Use AsyncStorage.removeItem('notes') and update the notes state to an empty array