Bird
Raised Fist0
React Nativemobile~20 mins

Realm database in React Native - Mini App: Build & Ship

Choose your learning style10 modes available
Build: Simple Realm Todo List
A screen that shows a list of todo items stored in Realm database. Users can add new todos and see them saved persistently.
Target UI
-------------------------
| Simple Realm Todo List |
-------------------------
| + Add Todo             |
|-----------------------|
| - [ ] Buy groceries    |
| - [ ] Walk the dog     |
|-----------------------|
Use Realm database to store todo items locally
Display a list of todos from Realm
Add a button to add a new todo with a text input prompt
Save new todos to Realm and update the list immediately
Each todo has a text and a boolean 'done' status (default false)
Starter Code
React Native
import React, { useEffect, useState } from 'react';
import { View, Text, Button, FlatList, TextInput, Alert } from 'react-native';
import Realm from 'realm';

const TodoSchema = {
  name: 'Todo',
  properties: {
    _id: 'string',
    text: 'string',
    done: { type: 'bool', default: false }
  },
  primaryKey: '_id',
};

export default function RealmTodoList() {
  const [realm, setRealm] = useState(null);
  const [todos, setTodos] = useState([]);
  const [newTodoText, setNewTodoText] = useState('');

  useEffect(() => {
    // TODO: Open Realm and load todos

    return () => {
      // TODO: Close Realm when component unmounts
    };
  }, []);

  const addTodo = () => {
    // TODO: Add new todo to Realm and update list
  };

  return (
    <View style={{ flex: 1, padding: 20 }}>
      <Text style={{ fontSize: 24, marginBottom: 10 }}>Simple Realm Todo List</Text>
      <TextInput
        placeholder="Enter new todo"
        value={newTodoText}
        onChangeText={setNewTodoText}
        style={{ borderWidth: 1, borderColor: '#ccc', padding: 8, marginBottom: 10 }}
      />
      <Button title="+ Add Todo" onPress={addTodo} />
      <FlatList
        data={todos}
        keyExtractor={item => item._id}
        renderItem={({ item }) => <Text>- [ ] {item.text}</Text>}
        style={{ marginTop: 20 }}
      />
    </View>
  );
}
Task 1
Task 2
Task 3
Task 4
Solution
React Native
import React, { useEffect, useState } from 'react';
import { View, Text, Button, FlatList, TextInput, Alert } from 'react-native';
import Realm from 'realm';
import 'react-native-get-random-values';
import { v4 as uuidv4 } from 'uuid';

const TodoSchema = {
  name: 'Todo',
  properties: {
    _id: 'string',
    text: 'string',
    done: { type: 'bool', default: false }
  },
  primaryKey: '_id',
};

export default function RealmTodoList() {
  const [realm, setRealm] = useState(null);
  const [todos, setTodos] = useState([]);
  const [newTodoText, setNewTodoText] = useState('');

  useEffect(() => {
    Realm.open({ schema: [TodoSchema] }).then(r => {
      setRealm(r);
      const allTodos = r.objects('Todo');
      setTodos([...allTodos]);

      allTodos.addListener(() => {
        setTodos([...allTodos]);
      });
    });

    return () => {
      if (realm !== null && !realm.isClosed) {
        realm.close();
      }
    };
  }, []);

  const addTodo = () => {
    if (newTodoText.trim() === '') {
      Alert.alert('Please enter a todo text');
      return;
    }
    realm.write(() => {
      realm.create('Todo', {
        _id: uuidv4(),
        text: newTodoText.trim(),
        done: false
      });
    });
    setNewTodoText('');
  };

  return (
    <View style={{ flex: 1, padding: 20 }}>
      <Text style={{ fontSize: 24, marginBottom: 10 }}>Simple Realm Todo List</Text>
      <TextInput
        placeholder="Enter new todo"
        value={newTodoText}
        onChangeText={setNewTodoText}
        style={{ borderWidth: 1, borderColor: '#ccc', padding: 8, marginBottom: 10 }}
        accessibilityLabel="New todo input"
      />
      <Button title="+ Add Todo" onPress={addTodo} accessibilityLabel="Add todo button" />
      <FlatList
        data={todos}
        keyExtractor={item => item._id}
        renderItem={({ item }) => <Text>- [ ] {item.text}</Text>}
        style={{ marginTop: 20 }}
        accessibilityLabel="Todo list"
      />
    </View>
  );
}

This solution uses Realm to store todo items locally on the device. We define a TodoSchema with an _id as primary key, a text string, and a done boolean.

Inside useEffect, we open Realm and load all todos into state. We also add a listener on the Realm collection to update the UI automatically when data changes.

The addTodo function writes a new todo with a unique ID generated by uuidv4(). After adding, it clears the input.

The UI shows a text input, an add button, and a list of todos. Accessibility labels are added for better screen reader support.

Final Result
Completed Screen
-------------------------
| Simple Realm Todo List |
-------------------------
| [input] Enter new todo |
| + Add Todo             |
|-----------------------|
| - [ ] Buy groceries    |
| - [ ] Walk the dog     |
| - [ ] Call mom         |
|-----------------------|
User types text in input field
User taps '+ Add Todo' button
New todo is saved in Realm and appears immediately in the list below
List updates automatically if todos change in Realm
Stretch Goal
Add the ability to toggle todo 'done' status by tapping on a todo item
💡 Hint
Use Realm write transactions to update the 'done' boolean and update the UI accordingly

Practice

(1/5)
1. What is the primary purpose of using Realm database in a React Native app?
easy
A. To handle app navigation between screens
B. To store data locally on the device for fast access
C. To style the app's user interface
D. To connect the app to a remote SQL server

Solution

  1. Step 1: Understand Realm's role

    Realm is a local database designed to store data on the device itself.
  2. Step 2: Compare options

    Options A, B, and C describe unrelated functions like navigation, remote servers, and UI styling, which Realm does not handle.
  3. Final Answer:

    To store data locally on the device for fast access -> Option B
  4. Quick Check:

    Realm = local data storage [OK]
Hint: Realm is for local data, not UI or navigation [OK]
Common Mistakes:
  • Confusing Realm with remote databases
  • Thinking Realm manages UI or navigation
  • Assuming Realm is a cloud service
2. Which of the following is the correct way to define a Realm schema for a Task object with a string name and a boolean completed property?
easy
A. const TaskSchema = {name: 'Task', properties: {name: 'string', completed: 'bool'}};
B. const TaskSchema = {name: 'Task', properties: {name: 'string', completed: 'boolean'}};
C. const TaskSchema = {name: 'Task', properties: {name: 'String', completed: 'Bool'}};
D. const TaskSchema = {name: 'Task', properties: {name: String, completed: Boolean}};

Solution

  1. Step 1: Check Realm property types

    Realm expects property types as lowercase strings like 'string' and 'bool'.
  2. Step 2: Compare options

    const TaskSchema = {name: 'Task', properties: {name: 'string', completed: 'bool'}}; uses correct lowercase strings. Options A, C, and D use incorrect types or JavaScript types instead of strings.
  3. Final Answer:

    const TaskSchema = {name: 'Task', properties: {name: 'string', completed: 'bool'}}; -> Option A
  4. Quick Check:

    Property types are lowercase strings [OK]
Hint: Use lowercase strings for property types in schema [OK]
Common Mistakes:
  • Using JavaScript types instead of strings
  • Capitalizing type names incorrectly
  • Omitting the 'properties' key
3. Given the following code snippet, what will be the output of console.log(tasks.length);?
const realm = await Realm.open({schema: [TaskSchema]});
realm.write(() => {
  realm.create('Task', {name: 'Buy milk', completed: false});
  realm.create('Task', {name: 'Walk dog', completed: true});
});
const tasks = realm.objects('Task');
console.log(tasks.length);
medium
A. 0
B. 1
C. 2
D. Undefined

Solution

  1. Step 1: Analyze write transaction

    Two Task objects are created inside the write block, so two entries are added.
  2. Step 2: Check objects query

    realm.objects('Task') returns all Task objects, so length should be 2.
  3. Final Answer:

    2 -> Option C
  4. Quick Check:

    Created 2 tasks, length = 2 [OK]
Hint: Count created objects inside write block [OK]
Common Mistakes:
  • Forgetting to use write block for create
  • Assuming objects() returns empty before commit
  • Confusing length with undefined
4. What is wrong with this Realm write transaction code? (Assume the TaskSchema defines name as the primary key)
realm.write(() => {
  realm.create('Task', {name: 'Read book', completed: false});
});
realm.write(() => {
  realm.create('Task', {name: 'Read book', completed: true});
});
medium
A. The second create will throw an error because a Task with the same primary key already exists
B. You cannot call realm.write() more than once
C. The second create will update the existing object automatically
D. There is no error; this code works fine

Solution

  1. Step 1: Check schema requirements

    With name as primary key, creating an object with the same primary key without update flag causes error.
  2. Step 2: Analyze code behavior

    The first create succeeds. The second create uses the same name (primary key) without update flag, so it throws an error.
  3. Final Answer:

    The second create will throw an error because a Task with the same primary key already exists -> Option A
  4. Quick Check:

    Duplicate primary key without update flag causes error [OK]
Hint: Use primary key and update flag to avoid create errors [OK]
Common Mistakes:
  • Assuming multiple writes are forbidden
  • Thinking create auto-updates without flags
  • Ignoring primary key requirements
5. You want to update the completed status of a Task object named 'Laundry' to true. (Assume the Task schema defines name as the primary key) Which code snippet correctly performs this update in Realm?
hard
A. realm.write(() => { realm.objects('Task').filtered('name == "Laundry"').completed = true; });
B. realm.write(() => { realm.create('Task', {name: 'Laundry', completed: true}); });
C. realm.write(() => { realm.update('Task', {name: 'Laundry', completed: true}); });
D. realm.write(() => { realm.create('Task', {name: 'Laundry', completed: true}, true); });

Solution

  1. Step 1: Understand update with create

    Realm updates existing objects if you pass true as the third argument to create.
  2. Step 2: Check each option

    realm.write(() => { realm.create('Task', {name: 'Laundry', completed: true}, true); }); uses true flag correctly. realm.write(() => { realm.create('Task', {name: 'Laundry', completed: true}); }); tries to create without update flag, causing error. realm.write(() => { realm.objects('Task').filtered('name == "Laundry"').completed = true; }); tries to assign directly to filtered results, which is invalid. realm.write(() => { realm.update('Task', {name: 'Laundry', completed: true}); }); uses a non-existent update method.
  3. Final Answer:

    realm.write(() => { realm.create('Task', {name: 'Laundry', completed: true}, true); }); -> Option D
  4. Quick Check:

    Use create with true flag to update [OK]
Hint: Use true flag in create to update existing objects [OK]
Common Mistakes:
  • Forgetting the update flag for updates
  • Trying to assign directly to query results
  • Using non-existent Realm methods
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard