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 template, you will:
Total Time: 60 minutes Difficulty: Beginner+ Prerequisites: Completed Activity 02 (Button Counter)
# 1. Navigate to this folder
cd activity-03-todo-list-basic
# 2. Install dependencies
npm install --legacy-peer-deps
# 3. Start Expo development server
npx expo start
# 4. Scan QR code with Expo Go app on your phone
# OR press 'w' to open in web browser
What You'll See Initially:
One. TodoItem Component (components/TodoItem.js)
2. EmptyState Component (components/EmptyState.js)
3. AddTodoForm Component (components/AddTodoForm.js)
4. Helper Functions (utils/todoHelpers.js)
generateId() - Creates unique IDs for todosisValidTodoText() - Validates inputformatTodoCount() - Formats task count5. Complete UI Structure
File: App.js (around line 15)
Goal: Set up React state to store array of todo objects
What You Need to Do:
// Find this comment in App.js:
// TODO #1: Initialize todos array state
// Add this code:
const [todos, setTodos] = useState([]);
Why This Matters:
{ id, text, completed }Test It:
File: App.js (around line 30)
Goal: Create function to add new todo to the array
What You Need to Do:
const addTodo = () => {
// Step 1: Validate input (don't add empty todos)
if (!inputText.trim()) {
return;
}
// Step 2: Create new todo object
const newTodo = {
id: generateId(),
text: inputText.trim(),
completed: false,
};
// Step 3: Add to array immutably
setTodos([...todos, newTodo]);
// Step 4: Clear input field
setInputText('');
};
Key Concepts:
inputText.trim() removes spaces, check if empty[...todos, newTodo] creates NEW arraytodos.push(newTodo) - React won't detect this change!Test It:
Common Mistakes:
todos.push() - mutates stateFile: App.js (around line 55)
Goal: Create function to remove todo from array by ID
What You Need to Do:
const deleteTodo = (id) => {
// Filter creates NEW array excluding the deleted todo
const updatedTodos = todos.filter(todo => todo.id !== id);
setTodos(updatedTodos);
};
Key Concepts:
todo.id !== id keeps everything EXCEPT deleted itemfilter() automatically returns new arrayAlternative One-Liner:
const deleteTodo = (id) => {
setTodos(todos.filter(todo => todo.id !== id));
};
Test It:
Common Mistakes:
splice() - mutates original array=== instead of !==Your completed activity should:
Functionality:
Code Quality:
Basic Operations:
Edge Cases:
Want to go further? Try these:
// โ
CORRECT: Immutable updates
setTodos([...todos, newTodo]); // Add
setTodos(todos.filter(t => t.id !== id)); // Remove
setTodos(todos.map(t => t.id === id ? {...t, completed: true} : t)); // Update
React uses referential equality to detect changes:
push() don't create new reference<FlatList
data={todos}
keyExtractor={(item) => item.id} // Must be unique!
renderItem={({ item }) => <TodoItem todo={item} />}
ListEmptyComponent={<EmptyState />}
/>
This activity teaches patterns you'll use in:
Project 1 (Weeks 1-2): Portfolio App
Project 2 (Weeks 3-4): Social App
Future Activities:
# Try clearing Expo cache
npx expo start --clear
useState is imported from 'react'[...todos, newTodo]!== not ==={
"expo": "~54.0.0",
"react": "18.3.1",
"react-native": "0.79.5",
"expo-status-bar": "~2.0.0"
}
No external libraries needed! Everything uses React Native core components.
React Native Docs:
React Docs:
After completing this activity:
Need Help?
Good luck! You've got this! ๐