React Native如何将数组传递到其他屏幕?已删除任务展示问题
React Native 待办应用:如何展示已删除任务到第二个屏幕
我正在开发一个入门级React Native待办应用,功能包括列出进行中的任务、删除任务、查看已删除任务。目前已能在一个屏幕展示所有任务,但不知道如何将筛选后的已删除任务(status为'deleted')展示到第二个屏幕。
现有代码
App.tsx
import { useState } from 'react'; import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import InputTasks from './screens/InputTasks'; import DeletedTasks from './screens/DeletedTasks'; const Stack = createNativeStackNavigator(); export default function App() { return ( <NavigationContainer> <Stack.Navigator screenOptions={{ headerStyle: { backgroundColor: 'green', }, headerTintColor: '#fff', }}> <Stack.Screen name="Home" component={InputTasks} /> <Stack.Screen name="Message" component={DeletedTasks} /> </Stack.Navigator> </NavigationContainer> ); }
InputTasks.tsx
import { Button, StyleSheet, Text, TextInput, View, TouchableOpacity } from 'react-native'; import React, { useState } from 'react'; import { useNavigation } from '@react-navigation/native'; const InputTasks = () => { const [newTask, setNewTask] = useState({}); //add a task const [taskList, setTaskList] = useState([]); //store all tasks in taskList array //add the typed task by the user in taskList array function addTodoHandler(){ setTaskList([...taskList,newTask]) } //change the status of task to 'deleted' so it can be shown in DeletedTasks screen const deleteTask = (taskId)=>{ const tasks = taskList.map((task)=>{ if (task.id == taskId){ task.status = 'deleted' } return task; }) setTaskList([...tasks]); } const navigation = useNavigation(); const goToMessageScreen = () => { navigation.navigate('Message', { newTask, }); }; return ( <View style={styles.container}> <View style={styles.contentContainer}> <View> <Text style={styles.sectionTitle}>TO-DO LIST</Text> </View> <View> {taskList.map((task)=>( <> <View> <View> <Text key={task}>{task.activity}</Text> </View> <View> <TouchableOpacity style={styles.deleteButton} onPress={()=>deleteTask(task.id)}> <Text>Delete</Text> </TouchableOpacity> </View> </View> </> ))} </View> </View> <View style={styles.taskWrapper}> <TextInput placeholder="Enter your message here" value={newTask} onChangeText={(enteredText) => setNewTask({id:taskList.length+1, activity:enteredText, status:'active'})} style={styles.input} /> <Button title="Submit" onPress={goToMessageScreen} color="green" /> <Button title="Add Task" onPress={addTodoHandler} color="green" /> </View> </View> ); }; export default InputTasks;
DeletedTasks.tsx
import { StyleSheet, Text, View } from 'react-native'; import React from 'react'; import { useRoute } from '@react-navigation/native'; const DeletedTasks = () => { const route = useRoute(); return ( <View style={styles.container}> <Text> </Text> </View> ); }; export default DeletedTasks;
解决方案
1. 将任务状态提升到App组件
当前任务列表taskList仅存在于InputTasks组件中,DeletedTasks无法直接访问。需将状态提升到父组件App,通过路由参数传递给两个子组件:
import { useState } from 'react'; import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import InputTasks from './screens/InputTasks'; import DeletedTasks from './screens/DeletedTasks'; const Stack = createNativeStackNavigator(); export default function App() { // 把任务列表状态放到App组件 const [taskList, setTaskList] = useState([]); return ( <NavigationContainer> <Stack.Navigator screenOptions={{ headerStyle: { backgroundColor: 'green', }, headerTintColor: '#fff', }}> <Stack.Screen name="Home" component={InputTasks} // 传递taskList和setTaskList给InputTasks initialParams={{ taskList, setTaskList }} /> <Stack.Screen name="Message" component={DeletedTasks} // 传递taskList给DeletedTasks initialParams={{ taskList }} /> </Stack.Navigator> </NavigationContainer> ); }
2. 修改InputTasks组件接收并使用props
调整InputTasks接收父组件传递的状态,同时修复状态更新逻辑、列表key等问题:
import { Button, StyleSheet, Text, TextInput, View, TouchableOpacity } from 'react-native'; import React, { useState } from 'react'; import { useNavigation, RouteProp } from '@react-navigation/native'; // 定义任务类型 type Task = { id: number; activity: string; status: 'active' | 'deleted'; }; type InputTasksProps = { route: RouteProp<{ Home: { taskList: Task[]; setTaskList: React.Dispatch<React.SetStateAction<Task[]>> } }, 'Home'>; }; const InputTasks = ({ route }: InputTasksProps) => { // 从props中获取taskList和setTaskList const { taskList, setTaskList } = route.params; // 初始化newTask为符合结构的对象 const [newTask, setNewTask] = useState<Task>({ id: 1, activity: '', status: 'active' }); // 添加任务 function addTodoHandler() { // 避免添加空任务 if (!newTask.activity.trim()) return; setTaskList([...taskList, newTask]); // 重置输入框 setNewTask({ id: taskList.length + 2, activity: '', status: 'active' }); } // 删除任务(遵循React状态不可变原则) const deleteTask = (taskId: number) => { const updatedTasks = taskList.map((task) => task.id === taskId ? { ...task, status: 'deleted' } : task ); setTaskList(updatedTasks); }; const navigation = useNavigation(); const goToMessageScreen = () => { navigation.navigate('Message'); }; return ( <View style={styles.container}> <View style={styles.contentContainer}> <View> <Text style={styles.sectionTitle}>TO-DO LIST</Text> </View> <View> {/* 只展示active状态的任务 */} {taskList .filter(task => task.status === 'active') .map((task) => ( <View key={task.id} style={styles.taskItem}> <Text>{task.activity}</Text> <TouchableOpacity style={styles.deleteButton} onPress={() => deleteTask(task.id)}> <Text>Delete</Text> </TouchableOpacity> </View> ))} </View> </View> <View style={styles.taskWrapper}> <TextInput placeholder="Enter your message here" value={newTask.activity} onChangeText={(enteredText) => setNewTask({ ...newTask, activity: enteredText, id: taskList.length + 1 }) } style={styles.input} /> <Button title="View Deleted" onPress={goToMessageScreen} color="green" /> <Button title="Add Task" onPress={addTodoHandler} color="green" /> </View> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, padding: 20, }, contentContainer: { flex: 1, marginBottom: 20, }, sectionTitle: { fontSize: 20, fontWeight: 'bold', marginBottom: 15, }, taskItem: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', padding: 10, borderBottomWidth: 1, borderBottomColor: '#eee', marginBottom: 5, }, deleteButton: { padding: 8, backgroundColor: '#ff4444', borderRadius: 4, }, taskWrapper: { gap: 10, }, input: { borderWidth: 1, borderColor: '#ccc', padding: 10, borderRadius: 4, }, }); export default InputTasks;
3. 修改DeletedTasks组件展示已删除任务
在DeletedTasks中接收任务列表,筛选出status为deleted的任务并展示:
import { StyleSheet, Text, View, FlatList } from 'react-native'; import React from 'react'; import { RouteProp } from '@react-navigation/native'; type Task = { id: number; activity: string; status: 'active' | 'deleted'; }; type DeletedTasksProps = { route: RouteProp<{ Message: { taskList: Task[] } }, 'Message'>; }; const DeletedTasks = ({ route }: DeletedTasksProps) => { const { taskList } = route.params; // 筛选已删除的任务 const deletedTasks = taskList.filter(task => task.status === 'deleted'); return ( <View style={styles.container}> <Text style={styles.sectionTitle}>DELETED TASKS</Text> {deletedTasks.length === 0 ? ( <Text>No deleted tasks yet.</Text> ) : ( <FlatList data={deletedTasks} keyExtractor={(item) => item.id.toString()} renderItem={({ item }) => ( <View style={styles.taskItem}> <Text>{item.activity}</Text> </View> )} /> )} </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, padding: 20, }, sectionTitle: { fontSize: 20, fontWeight: 'bold', marginBottom: 15, }, taskItem: { padding: 10, borderBottomWidth: 1, borderBottomColor: '#eee', marginBottom: 5, }, }); export default DeletedTasks;
核心说明
- 状态提升:将共享任务列表状态放到父组件
App,确保两个子组件都能访问最新数据。 - 不可变更新:修改任务状态时通过复制新对象实现,保证React能正确检测状态变化并触发重新渲染。
- 路由参数传递:通过
initialParams将状态传递给各个屏幕,实现跨组件数据共享。
内容的提问来源于stack exchange,提问作者buckwheat
相关产品推荐
相关产品推荐

