Student starter code (30% baseline)
index.html- Main HTML pagescript.js- JavaScript logicstyles.css- Styling and layoutpackage.json- Dependenciessetup.sh- Setup scriptREADME.md- Instructions (below)๐ก Download the ZIP, extract it, and follow the instructions below to get started!
By completing this activity, you will:
useState to manage application stateonPress eventsTotal Time: 45 minutes Difficulty: Beginner Concept: Components and Basic Styling
# Extract the ZIP file you downloaded
# Open terminal and navigate to the folder
cd activity-02-button-counter
# Install all required packages (takes ~30 seconds)
npm install --legacy-peer-deps
# Start Expo
npx expo start
# Then:
# - Press 'w' to open in web browser, OR
# - Scan QR code with Expo Go app on your phone
Success! You should see a working app with two buttons (+ and -).
This template comes pre-built with:
components/ActionButton.jsstyles/buttonStyles.jscolors.primary, colors.danger, etc.styles/colors.jsutils/helpers.jsFile: App.js (line ~37)
What to do: Uncomment the useState line to create counter state.
Code to uncomment:
const [count, setCount] = useState(0);
Why this matters: State is how React Native remembers data and re-renders when it changes. Without state, the counter won't update!
Test it: After uncommenting, save the file. The app should reload without errors (you won't see visual changes yet).
File: App.js (line ~43)
What to do: Make the + button work by updating count.
Implementation:
const handleIncrement = () => {
setCount(count + 1);
};
Key concepts:
setCount) to update statecount++ won't work!)Test it: The + button should increase the count (once you complete TODO #4 to see the display).
File: App.js (line ~49)
What to do: Make the - button work by decreasing count.
Implementation:
const handleDecrement = () => {
setCount(count - 1);
};
Test it: The - button should decrease the count. The counter can go negative (that's okay for now!).
File: components/CounterDisplay.js
What to do: Create a component that displays the count with large, readable text.
Complete implementation:
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { colors } from '../styles/colors';
export default function CounterDisplay({ count, color }) {
return (
<View style={styles.container}>
<Text style={styles.label}>Count</Text>
<Text style={[styles.count, { color: color || colors.primary }]}>
{count}
</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
alignItems: 'center',
marginVertical: 20,
},
label: {
fontSize: 16,
color: colors.gray,
marginBottom: 8,
},
count: {
fontSize: 64,
fontWeight: 'bold',
},
});
Then, in App.js: Uncomment the CounterDisplay usage (line ~73).
Test it: You should see a large number displaying the count. Try pressing + and - to see it update!
File: components/ResetButton.js
What to do: Create a red button that resets the counter to 0.
Complete implementation:
import React from 'react';
import { TouchableOpacity, Text, StyleSheet } from 'react-native';
import { colors } from '../styles/colors';
export default function ResetButton({ onPress }) {
return (
<TouchableOpacity style={styles.button} onPress={onPress}>
<Text style={styles.text}>Reset</Text>
</TouchableOpacity>
);
}
const styles = StyleSheet.create({
button: {
backgroundColor: colors.danger,
paddingVertical: 12,
paddingHorizontal: 24,
borderRadius: 8,
minHeight: 44,
justifyContent: 'center',
alignItems: 'center',
marginTop: 20,
},
text: {
color: '#FFFFFF',
fontSize: 16,
fontWeight: '600',
},
});
Then, in App.js:
handleReset function body (line ~56)Test it: You should see a red "Reset" button. Clicking it should return the count to 0.
File: App.js (line ~75)
What to do: Change the counter color based on value (green for positive, red for negative, blue for zero).
Implementation: Update the CounterDisplay usage:
<CounterDisplay
count={count}
color={count > 0 ? colors.success : count < 0 ? colors.danger : colors.primary}
/>
How it works:
condition ? true : falseTest it:
Issue: "useState is not defined"
Solution: Check that you have import { useState } from 'react'; at the top of App.js
Issue: "Cannot read property 'success' of undefined"
Solution: Make sure you imported colors: import { colors } from './styles/colors';
Issue: Buttons don't do anything
Solution: Check that handleIncrement and handleDecrement are calling setCount()
Issue: Count doesn't display Solution: Verify you uncommented the CounterDisplay usage in App.js
Add Step Size: Allow incrementing by 5 or 10 instead of just 1
Disable at Limits: Prevent count from going below 0 or above 100
History Feature: Track all changes and display a list
[history, setHistory]Custom Step Input: Add a text input to set custom step size
Smooth Animations: Add fade-in effect when count changes
Sound Effects: Play a sound on button press
npx expo install expo-avWhat it is: A React hook that adds state to functional components.
Syntax: const [value, setValue] = useState(initialValue)
Why it matters: Without state, your app can't remember or react to changes. State triggers re-renders when updated.
Common mistake: Mutating state directly
// โ Wrong
count = count + 1;
// โ
Correct
setCount(count + 1);
What they are: Functions that run when user interactions happen.
Syntax: onPress={handlePress} (pass function reference, not call it!)
Common mistake: Calling function instead of passing reference
// โ Wrong - executes immediately
<Button onPress={handlePress()} />
// โ
Correct - executes on press
<Button onPress={handlePress} />
What they are: Data passed from parent to child components.
Why they matter: Makes components reusable and composable.
Example: <CounterDisplay count={5} color="red" />
Project 1 (M1): Uses these button patterns and state management concepts extensively.
Project 2 (M1): Extends state management to more complex data structures.
Real-world apps: Every interactive app uses state and events. You're building the foundation!
Understanding: Explain useState in your own words. Why can't we just use regular variables?
Application: How would you use state to build a "like" button for social media posts?
Challenges: What was most difficult about managing state? How did you overcome it?
๐ Congratulations on completing Activity 02!
You've mastered:
Next Steps:
Activity 02 | M1: Mobile Foundations | React Native & Expo SDK 54