Todo List 应用——核心组件与 Hooks

知识库
知识库文档
/tech-stacks/react-native/examples/Todo List 应用——核心组件与 Hooks.md

文档

React Native 例程:Todo List——FlatList 与状态管理

目标

通过一个功能完整的 Todo List,展示 RN 核心:FlatList、TextInput、useState、StyleSheet、TouchableOpacity。

完整代码

// App.js
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
# 将上面代码覆盖 App.js
npx expo start
# 扫码运行

预期表现

  • 输入框提交新任务
  • 点击 ⬜ → ✅ 标记完成(文字加删除线)
  • 点击 🗑️ 弹出确认后删除
  • FlatList 高效渲染长列表

信息

路径
/tech-stacks/react-native/examples/Todo List 应用——核心组件与 Hooks.md
更新时间
2026/5/31