React Native Todo应用点击单个任务触发全选完成的问题求助
问题原因
你在App组件里用了一个全局的isCompleted状态变量,所有Task组件都共享这个状态。点击任意任务时触发的是全局状态更新,所有任务都会读取同一个isCompleted值,因此全部同步切换完成状态。
解决方案
让每个任务独立维护自己的完成状态,而非依赖全局状态。具体修改如下:
1. 修改App.js
- 移除全局的
isCompleted状态 - 调整任务数据结构,每个任务是包含
text和isCompleted的对象 - 添加切换单个任务完成状态的函数
- 渲染Task时传递对应任务的状态和切换函数
修改后的App.js代码:
import { StatusBar } from 'expo-status-bar'; import { useState, React } from 'react'; import { StyleSheet, SafeAreaView, Text, View, TextInput, TouchableOpacity, Platform, Keyboard } from 'react-native'; import { useColorScheme } from "nativewind"; import Task from './components/Task.js' import KeyboardAvoidingView from 'react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js'; export default function App() { const { colorScheme, toggleColorScheme } = useColorScheme(); const [task, setTask] = useState() const [taskItems, setTaskItems] = useState([]) const addTask = () => { Keyboard.dismiss() // 每个任务对象包含文本和完成状态 setTaskItems([...taskItems, { text: task, isCompleted: false }]) setTask(null) } // 切换指定索引任务的完成状态 const toggleTaskCompletion = (index) => { const updatedTasks = [...taskItems]; updatedTasks[index].isCompleted = !updatedTasks[index].isCompleted; setTaskItems(updatedTasks); } const deleteTask = () => { } const updateTask = () => { } return ( <SafeAreaView className="bg-gray-500/20 flex-1 dark:bg-black/90 overflow-auto"> <View className="w-full sticky top-0 left-0 flex items-end px-5 h-10 justify-center"> <TouchableOpacity onPress={toggleColorScheme}> <Text className="dark:text-white"> {colorScheme === "dark" ? `🌙 ${colorScheme}` : `🌞 ${colorScheme}`} </Text> </TouchableOpacity> </View> <View className="mt-5 px-5"> { taskItems.map((item, index) => { // 传递单个任务的状态、切换函数和索引 return <Task key={index} item={item} toggleTaskCompletion={() => toggleTaskCompletion(index)} /> }) } </View> <KeyboardAvoidingView style={styles.addTask} behavior={Platform.OS === "ios" ? "padding" : "height"}> <View> <TextInput onChangeText={text => setTask(text)} value={task} className="relative border px-5 py-5 border-gray-500/20 focus:border-gray-500 rounded-xl dark:text-white pr-16" placeholder='Lets! Tell me something to do' placeholderTextColor={colorScheme === "dark" ? "#fff" : "#000"}></TextInput> <TouchableOpacity onPress={() => addTask()} className="px-5 py-2 absolute right-0 top-0 h-full justify-center items-center"> <Text>Add</Text> </TouchableOpacity> </View> </KeyboardAvoidingView> <StatusBar style="auto" /> </SafeAreaView > ); } const styles = StyleSheet.create({ addTask: { position: 'absolute', left: 0, bottom: 40, width: "100%", paddingHorizontal: 20 } })
2. 修改Task组件
调整组件接收的props,使用单个任务的状态控制样式和文本效果,点击时触发对应任务的切换函数:
import React from "react"; import { View, Text, TouchableOpacity } from "react-native"; const Task = (props) => { return ( <TouchableOpacity onPress={props.toggleTaskCompletion} className={`mt-5 dark:bg-white p-5 rounded-xl ${props.item.isCompleted ? 'bg-pink-200' : 'bg-white'}`}> <Text className={`${props.item.isCompleted ? 'text-white line-through' : ''}`}> {props.item.text} </Text> </TouchableOpacity> ) } export default Task;
修改后每个任务都有独立的完成状态,点击单个任务只会切换该任务的状态,不会影响其他任务。
内容的提问来源于stack exchange,提问作者user14201902
相关产品推荐
相关产品推荐

