Practice and reinforce the concepts from Lesson 11
Practice systematic debugging by finding and fixing 10 intentional bugs in a seemingly-working app.
import React, { useState, useEffect } from 'react';
import { View, Text, Button, TextInput, FlatList } from 'react-native';
const MysteryApp = () => {
const [users, setUsers] = useState([]);
const [newUser, setNewUser] = useState('');
const [loading, setLoading] = useState(false);
const [selectedUser, setSelectedUser] = useState(null);
useEffect(() => {
loadUsers();
}, []);
const loadUsers = async () => {
setLoading(true);
// Simulated API call
setTimeout(() => {
setUsers([
{ id: 1, name: 'Alice', email: 'alice@test.com', active: true },
{ id: 2, name: 'Bob', email: 'bob@test.com', active: false },
{ id: 3, name: 'Charlie', email: 'charlie@test.com', active: true }
]);
setLoading(true); // Bug #1: Should be false
}, 1000);
};
const addUser = () => {
if (newUser.length > 0) {
const newId = users.length + 1; // Bug #2: Not reliable for unique IDs
setUsers([...users, {
id: newId,
name: newUser,
email: `${newUser}@test.com`,
active: true
}]);
setNewUser('');
}
};
const deleteUser = (id) => {
setUsers(users.filter(user => user.id !== id));
if (selectedUser && selectedUser.id === id) {
setSelectedUser(null); // Bug #3: Actually correct - not a bug!
}
};
const toggleUserStatus = (id) => {
setUsers(users.map(user =>
user.id == id // Bug #4: Should use strict equality (===)
? { ...user, active: !user.active }
: user
));
};
return (
<View style={{padding: 20}}>
<Text style={{fontSize: 24, marginBottom: 20}}>User Manager</Text>
{loading && <Text>Loading users...</Text>}
<TextInput
value={newUser}
onChangeText={setNewUser}
placeholder="Enter user name"
style={{borderWidth: 1, padding: 10, marginBottom: 10}}
/>
<Button title="Add User" onPress={addUser} />
<FlatList
data={users}
keyExtractor={(item) => item.id} // Bug #5: Should convert to string
renderItem={({item}) => (
<View style={{
padding: 10,
margin: 5,
backgroundColor: item.active ? 'lightgreen' : 'lightgray',
borderColor: selectedUser?.id === item.id ? 'blue' : 'gray',
borderWidth: 2
}}>
<Text style={{fontSize: 16}}>{item.name}</Text>
<Text>{item.email}</Text>
<Text>Status: {item.active ? 'Active' : 'Inactive'}</Text>
<View style={{flexDirection: 'row', marginTop: 10}}>
<Button
title="Select"
onPress={() => setSelectedUser(item)}
/>
<Button
title={item.active ? 'Deactivate' : 'Activate'}
onPress={() => toggleUserStatus(item.id)}
/>
<Button
title="Delete"
onPress={() => deleteUser(item.id)}
color="red"
/>
</View>
</View>
)}
/>
{selectedUser && (
<View style={{marginTop: 20, padding: 15, backgroundColor: 'lightyellow'}}>
<Text style={{fontSize: 18}}>Selected User:</Text>
<Text>Name: {selectedUser.name}</Text>
<Text>Email: {selectedUser.email}</Text>
<Text>Status: {selectedUser.active ? 'Active' : 'Inactive'}</Text>
{/* Bug #6: Selected user info doesn't update when status changes */}
</View>
)}
</View>
);
};
export default MysteryApp;
Run through these basic operations:
What feels broken or weird?
Find these 10 bugs (5 are marked above, 5 are hidden):
Obvious Bugs (marked in comments):
Hidden Bugs (find these!):
Rank the bugs by severity:
You should identify:
Fix all 10 bugs and test your solutions!
Complete this activity and submit your work through the Activity Submission Form