React Native 例程:Todo List——FlatList 与状态管理
目标
通过一个功能完整的 Todo List,展示 RN 核心:FlatList、TextInput、useState、StyleSheet、TouchableOpacity。
完整代码
import React, { useState } from 'react';
import {
View,
Text,
TextInput,
TouchableOpacity,
FlatList,
StyleSheet,
Alert,
} from 'react-native';
export default function App() {
const [todos, setTodos] = useState([]);
const [inputText, setInputText] = useState('');
const addTodo = () => {
if (inputText.trim() === '') return;
setTodos([
...todos,
{
id: Date.now().toString(),
text: inputText.trim(),
completed: false,
},
]);
setInputText('');
};
const toggleTodo = (id) => {
setTodos(
todos.map((todo) =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
)
);
};
const deleteTodo = (id) => {
Alert.alert('确认', '删除这条任务?', [
{ text: '取消', style: 'cancel' },
{
text: '删除',
style: 'destructive',
onPress: () => setTodos(todos.filter((t) => t.id !== id)),
},
]);
};
const renderItem = ({ item }) => (
<View style={styles.todoItem}>
<TouchableOpacity
style={styles.checkbox}
onPress={() => toggleTodo(item.id)}
>
<Text style={styles.checkText}>
{item.completed ? '✅' : '⬜'}
</Text>
</TouchableOpacity>
<Text
style={[
styles.todoText,
item.completed && styles.completedText,
]}
>
{item.text}
</Text>
<TouchableOpacity onPress={() => deleteTodo(item.id)}>
<Text style={styles.deleteBtn}>🗑️</Text>
</TouchableOpacity>
</View>
);
return (
<View style={styles.container}>
<Text style={styles.title}>📋 Todo List</Text>
<View style={styles.inputRow}>
<TextInput
style={styles.input}
placeholder="输入新任务..."
value={inputText}
onChangeText={setInputText}
onSubmitEditing={addTodo}
/>
<TouchableOpacity style={styles.addBtn} onPress={addTodo}>
<Text style={styles.addBtnText}>+</Text>
</TouchableOpacity>
</View>
<FlatList
data={todos}
keyExtractor={(item) => item.id}
renderItem={renderItem}
ListEmptyComponent={
<Text style={styles.empty}>暂无任务,添加一个吧 ✨</Text>
}
/>
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, paddingTop: 60, paddingHorizontal: 20, backgroundColor: '#f5f5f5' },
title: { fontSize: 28, fontWeight: 'bold', textAlign: 'center', marginBottom: 20 },
inputRow: { flexDirection: 'row', marginBottom: 16 },
input: {
flex: 1, borderWidth: 1, borderColor: '#ddd', borderRadius: 8,
paddingHorizontal: 12, paddingVertical: 10, fontSize: 16, backgroundColor: '#fff',
},
addBtn: {
marginLeft: 8, backgroundColor: '#007AFF', borderRadius: 8,
width: 44, justifyContent: 'center', alignItems: 'center',
},
addBtnText: { color: '#fff', fontSize: 24, fontWeight: 'bold' },
todoItem: {
flexDirection: 'row', alignItems: 'center', backgroundColor: '#fff',
padding: 14, borderRadius: 8, marginBottom: 8, elevation: 1,
},
checkbox: { marginRight: 10 },
checkText: { fontSize: 22 },
todoText: { flex: 1, fontSize: 16 },
completedText: { textDecorationLine: 'line-through', color: '#999' },
deleteBtn: { fontSize: 20, padding: 4 },
empty: { textAlign: 'center', color: '#999', marginTop: 40, fontSize: 16 },
});
运行步骤
npx create-expo-app@latest TodoRN
npx expo start
预期表现
- 输入框提交新任务
- 点击 ⬜ → ✅ 标记完成(文字加删除线)
- 点击 🗑️ 弹出确认后删除
- FlatList 高效渲染长列表