CodeBlanks Logo Icon CodeBlanks

Putting it together

Combine all layers into a working mini service app.

Putting all layers together

In the last lesson we wire all pieces: auth context, API fetch, camera, location and offline cache. On launch App first loads tasks from the cache with loadCache; then if useNetInfo reports a connection it refreshes from the API. With auth, the task list replaces the login screen.

This union is the skeleton of an advanced React Native app. Each layer was built in its own lesson; now they all work together. Cache gives a fast launch, auth gives secure access, native gives field features. In the next step you will start this flow with useEffect.

Practice Start the flow with useEffect

On top of the previous code add a useEffect. Its dependency array is [] (mount only). Inside it first call loadCache(), then call fetchTasks.

Starter code

App.js
import React, { useState, createContext, useContext } from 'react';
import { Text, View } from 'react-native';

const AuthContext = createContext(null);
export function useAuth() { return useContext(AuthContext); }

function App() {
  const [tasks, setTasks] = useState([]);
  const [user, setUser] = useState(null);
  return (
    <AuthContext.Provider value={{ user, setUser }}>
      <View>
        <Text>Field Report</Text>
      </View>
    </AuthContext.Provider>
  );
}

export function useCamera() {
  const [photo, setPhoto] = useState(null);
  const takePhoto = async () => {
    setPhoto('photo-uri');
  };
  return { photo, takePhoto };
}

async function loadCache() {
  const raw = await AsyncStorage.getItem('tasks');
  if (raw) {
    setTasks(JSON.parse(raw));
  }
}

// Start the flow with useEffect here

Sample solution

App.js
import React, { useState, createContext, useContext } from 'react';
import { Text, View } from 'react-native';

const AuthContext = createContext(null);
export function useAuth() { return useContext(AuthContext); }

function App() {
  const [tasks, setTasks] = useState([]);
  const [user, setUser] = useState(null);
  return (
    <AuthContext.Provider value={{ user, setUser }}>
      <View>
        <Text>Field Report</Text>
      </View>
    </AuthContext.Provider>
  );
}

export function useCamera() {
  const [photo, setPhoto] = useState(null);
  const takePhoto = async () => {
    setPhoto('photo-uri');
  };
  return { photo, takePhoto };
}

async function loadCache() {
  const raw = await AsyncStorage.getItem('tasks');
  if (raw) {
    setTasks(JSON.parse(raw));
  }
}

useEffect(() => {
  loadCache();
  fetchTasks();
}, []);

Questions and answers

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

1 What does App do first on launch?

App.js
useEffect(() => { /* ? */ }, []);
  • Loads from cache Correct answer
  • Signs out
  • Takes a photo
  • Changes the color

Explanation: Tasks load from the cache first.

2 Match each layer to its role

Term Meaning
AuthContext Login state
loadCache Loads from device
useCamera Takes a photo
NetInfo Watches connection

3 The dependency array

Question
useEffect(() => { loadCache(); fetchTasks(); }, ____);
Answer
useEffect(() => { loadCache(); fetchTasks(); }, []);

Explanation: The empty array runs only at mount.

4 How was offline achieved in this project?

App.js
AsyncStorage + NetInfo
  • With a theme
  • With an animation
  • With a cache Correct answer
  • With a notification

Explanation: AsyncStorage cache plus NetInfo gives offline work.

All lessons in Advanced