CodeBlanks Logo Icon CodeBlanks

Putting it together

Combine all parts into a working notes app.

Putting it together

In the final lesson we combine all parts into a working notes app. With useEffect we load the notes on mount, with a Button we add a new note, with AsyncStorage we save. All five lessons come together here.

First we will load notes from AsyncStorage with useEffect. Then we will add a Button that puts a new note into state when pressed. This is a small but complete app; the user adds a note, and on close and reopen the notes are restored. This lesson is the peak of the project series.

Practice Load notes with useEffect

Add useEffect to the NotesApp component. On mount read the saved notes with AsyncStorage.getItem("notes"). Parse the string into an array with JSON.parse and call setNotes. The dependency array is empty ([]).

Starter code

App.js
import { useState } from "react";
import { Text, TextInput } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";

function NotesApp() {
  const [notes, setNotes] = useState([{ id: "1", title: "Shopping", body: "Milk, bread" }]);
  const [title, setTitle] = useState("");
  const [body, setBody] = useState("");

  async function saveNotes() {
    await AsyncStorage.setItem("notes", JSON.stringify(notes));
  }

  // Add useEffect; load notes from AsyncStorage on mount
  // Parse to array with JSON.parse and call setNotes; array empty

  return <Text>Notes</Text>;
}

Sample solution

App.js
import { useEffect, useState } from "react";
import { Text, TextInput } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";

function NotesApp() {
  const [notes, setNotes] = useState([{ id: "1", title: "Shopping", body: "Milk, bread" }]);
  const [title, setTitle] = useState("");
  const [body, setBody] = useState("");

  async function saveNotes() {
    await AsyncStorage.setItem("notes", JSON.stringify(notes));
  }

  useEffect(() => {
    AsyncStorage.getItem("notes").then(raw => {
      if (raw) setNotes(JSON.parse(raw));
    });
  }, []);

  return <Text>Notes</Text>;
}

Practice Add button

Add a Button to the NotesApp component. On onPress add a new note with setNotes: { id: Date.now().toString(), title, body }. The component keeps returning <Text>Notes</Text>.

Starter code

App.js
import { useEffect, useState } from "react";
import { Text, TextInput } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";

function NotesApp() {
  const [notes, setNotes] = useState([{ id: "1", title: "Shopping", body: "Milk, bread" }]);
  const [title, setTitle] = useState("");
  const [body, setBody] = useState("");

  async function saveNotes() {
    await AsyncStorage.setItem("notes", JSON.stringify(notes));
  }

  useEffect(() => {
    AsyncStorage.getItem("notes").then(raw => {
      if (raw) setNotes(JSON.parse(raw));
    });
  }, []);

  // Add a Button; on press add a new note with setNotes
  // Use a timestamp for the id

  return <Text>Notes</Text>;
}

Sample solution

App.js
import { Button, useEffect, useState } from "react";
import { Text, TextInput } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";

function NotesApp() {
  const [notes, setNotes] = useState([{ id: "1", title: "Shopping", body: "Milk, bread" }]);
  const [title, setTitle] = useState("");
  const [body, setBody] = useState("");

  async function saveNotes() {
    await AsyncStorage.setItem("notes", JSON.stringify(notes));
  }

  useEffect(() => {
    AsyncStorage.getItem("notes").then(raw => {
      if (raw) setNotes(JSON.parse(raw));
    });
  }, []);

  return (
    <>
      <Button onPress={() => setNotes([...notes, { id: Date.now().toString(), title, body }])} title="Add" />
      <Text>Notes</Text>
    </>
  );
}

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 What does an empty dependency array do?

App.js
useEffect(() => {
  loadNotes();
}, []);
  • Runs on every render
  • Only on unmount
  • Runs only on mount Correct answer
  • It never runs

Explanation: An empty array makes the effect run only on mount.

2 Add a new note

Question
setNotes([...____, { id: Date.now().toString(), title, body }]);
Answer
setNotes([...notes, { id: Date.now().toString(), title, body }]);

Explanation: [...notes] copies the old notes into a new array.

3 Match each piece to its role

Term Meaning
useEffect Loads on mount
AsyncStorage.getItem Reads
Button onPress Adds a new note
setNotes Updates state

All lessons in Intermediate