Practice and reinforce the concepts from Lesson 2
Apply habit-forming principles by:
Time Limit: 10 minutes per app
Analyze these popular apps and identify their habit loops:
Apps to Analyze:
Analysis Framework:
App Name: ___________
📡 CUE (What triggers usage?):
- External:
- Internal:
🔁 ROUTINE (What's the main action?):
- Primary behavior:
- Time invested:
🏆 REWARD (What satisfaction do users get?):
- Variable reward type:
- Emotional payoff:
📊 INVESTMENT (How do users invest in the app?):
- Data/Content:
- Social connections:
- Time/Effort:
✅ Checkpoint: Fill out analysis for at least 2 apps
Time Limit: 10 minutes
Create a visual map of one app's habit loop:
npx create-expo-app HabitTracker --template blank
cd HabitTracker
npx expo start
Replace App.js
with this foundation:
import React, { useState, useEffect } from 'react';
import {
View,
Text,
StyleSheet,
TouchableOpacity,
FlatList,
Alert,
} from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
export default function App() {
const [habits, setHabits] = useState([
{ id: 1, name: 'Drink Water', streak: 0, completed: false, emoji: '💧' },
{ id: 2, name: 'Exercise', streak: 0, completed: false, emoji: '🏃' },
{ id: 3, name: 'Read', streak: 0, completed: false, emoji: '📚' },
]);
const [totalPoints, setTotalPoints] = useState(0);
// Your code will go here!
const completeHabit = (habitId) => {
// Implement habit completion logic
};
const renderHabit = ({ item }) => (
<TouchableOpacity
style={[
styles.habitCard,
item.completed && styles.completedCard,
]}
onPress={() => completeHabit(item.id)}
>
{/* Habit card content */}
</TouchableOpacity>
);
return (
<View style={styles.container}>
{/* App content goes here */}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f5f7fa',
paddingTop: 50,
paddingHorizontal: 20,
},
// Add your styles
});
Your Mission: Complete these functions to create addictive mechanics:
const [dailyReminder, setDailyReminder] = useState('Time to build habits!');
// Add visual cues
const getCueColor = (streak) => {
if (streak === 0) return '#ff6b6b'; // Red - needs attention
if (streak < 7) return '#ffa500'; // Orange - building
return '#32cd32'; // Green - strong habit
};
const completeHabit = (habitId) => {
setHabits(prev => prev.map(habit => {
if (habit.id === habitId && !habit.completed) {
const newStreak = habit.streak + 1;
setTotalPoints(p => p + (newStreak * 10)); // Increasing rewards!
return { ...habit, completed: true, streak: newStreak };
}
return habit;
}));
// Add celebration animation/feedback here!
};
const getRewardMessage = (streak) => {
if (streak === 1) return '🎉 Great start!';
if (streak === 7) return '💪 One week strong!';
if (streak === 30) return '🏆 Month champion!';
return `🔥 ${streak} day streak!`;
};
const showCelebration = () => {
// Variable reward - different celebration each time!
const celebrations = ['🎉', '🎨', '🎆', '✨', '🌈'];
const randomCelebration = celebrations[Math.floor(Math.random() * celebrations.length)];
Alert.alert(
'Habit Completed!',
`${randomCelebration} ${getRewardMessage(newStreak)}`
);
};
Implement different types of rewards:
const [unlockedBadges, setUnlockedBadges] = useState([]);
const badges = [
{ id: 'starter', name: 'First Step', icon: '🌱', requirement: 1 },
{ id: 'consistent', name: 'Consistent', icon: '🎆', requirement: 7 },
{ id: 'champion', name: 'Champion', icon: '🏆', requirement: 30 },
{ id: 'master', name: 'Habit Master', icon: '🥇', requirement: 100 },
];
const checkBadges = (streak) => {
badges.forEach(badge => {
if (streak >= badge.requirement && !unlockedBadges.includes(badge.id)) {
setUnlockedBadges(prev => [...prev, badge.id]);
Alert.alert('New Badge Unlocked!', `${badge.icon} ${badge.name}`);
}
});
};
const [shareStreak, setShareStreak] = useState(0);
const shareProgress = async (habit) => {
const message = `I've maintained my ${habit.name} habit for ${habit.streak} days! 🔥`;
// Implement sharing logic
setShareStreak(prev => prev + 1);
};
Create two different reward systems and test which feels more satisfying:
Version A: Linear Points
Version B: Exponential + Random
Test Question: Which version makes you want to continue more?
const [streakInsurance, setStreakInsurance] = useState(0);
const buyStreakInsurance = () => {
if (totalPoints >= 100) {
setTotalPoints(p => p - 100);
setStreakInsurance(prev => prev + 1);
Alert.alert('Streak Protected!', 'Your streak is safe for one missed day');
}
};
const handleMissedDay = (habitId) => {
// Give option to use streak insurance instead of losing progress
Alert.alert(
'Streak at Risk!',
'Use streak insurance to protect your progress?',
[
{ text: 'Lose Streak', onPress: () => resetStreak(habitId) },
{
text: 'Use Insurance (100 points)',
onPress: () => useStreakInsurance(habitId)
},
]
);
};
Implement perfect timing for habit reminders:
Add satisfying micro-interactions:
Create a compelling first experience:
const commitmentLevels = [
{ level: 1, description: 'Try for 3 days', reward: 50 },
{ level: 2, description: 'Commit to 1 week', reward: 200 },
{ level: 3, description: 'Go for 1 month', reward: 1000 },
];
const accountabilityPartner = {
name: 'Study Buddy',
sharedHabits: ['Exercise', 'Read'],
canSeeProgress: true,
};
const habitChains = [
{ trigger: 'Wake up', habit: 'Drink water', next: 'Exercise' },
{ trigger: 'Exercise', habit: 'Shower', next: 'Healthy breakfast' },
];
Document your app's habit loop:
App Successfully Creates Habits If:
Discussion Points:
Time Investment: 60 minutes total Difficulty Level: Intermediate Prerequisites: Basic React Native knowledge, understanding of psychology concepts Tools Needed: Computer, smartphone, notebook for analysis