React Native AsyncStorage实现不同班级独立存储学生列表问题咨询
问题根因
你当前的代码中所有班级的学生数据都统一存储在AsyncStorage的同一个固定key student 下,不管进入哪个班级,读写的都是同一份学生列表,所以才会出现班级A添加的学生同步出现在班级B中的问题。
修改思路
- 给每个班级分配独立的AsyncStorage存储key,规则为
students_${班级ID},通过班级ID区分不同班级的学生数据 - 删除班级时同步删除对应班级的学生存储数据,避免冗余存储
- 进入班级页面时,根据当前传入的班级ID读取对应班级的学生列表
具体修改代码
1. MainMenu.js 仅需修改删除班级方法
其余代码保持不变,仅更新deleteClassroom方法,删除班级时同步清理对应学生数据:
// 替换原有的deleteClassroom方法 const deleteClassroom = async (classroomId) => { const newClassrooms = classroom.filter(item => item.id !== classroomId); setClassroom(newClassrooms); // 新增:删除当前班级对应的学生存储数据 try { await AsyncStorage.removeItem(`students_${classroomId}`); } catch (error) { console.log(error); } };
2. Classroom.js 全量修改(核心修改已标注)
import React, { useState , useEffect } from 'react'; import { View, Text, TouchableOpacity, FlatList, Alert, TextInput, StyleSheet, } from 'react-native'; import Icon from 'react-native-vector-icons/MaterialIcons'; import AsyncStorage from '@react-native-async-storage/async-storage'; import { useRoute } from '@react-navigation/core'; const Classroom = ( {navigation}) => { const [studentInput, setStudentInput] = useState(''); const [student, setStudent] = useState([]); const route = useRoute(); // 新增:获取当前班级ID,生成专属存储key const currentClassId = route.params.id; const studentStorageKey = `students_${currentClassId}`; // 修改:依赖项增加班级ID,切换班级时重新加载对应学生 useEffect(() => { getStudent(); }, [currentClassId]); useEffect(() => { saveStudent(student); }, [student]); const saveStudent = async (student) => { try { const stringifyStudent = JSON.stringify(student); // 修改:用当前班级专属key存储 await AsyncStorage.setItem(studentStorageKey, stringifyStudent); } catch (error) { console.log(error); } }; const getStudent = async () => { try { // 修改:用当前班级专属key读取 const students = await AsyncStorage.getItem(studentStorageKey); if (students !== null) { setStudent(JSON.parse(students)); } else { // 新增:当前班级无学生数据时清空列表 setStudent([]); } } catch (error) { console.log(error); } }; const addStudent = () => { if (studentInput === ''){ Alert.alert('Error', 'Please input student name'); } else { const newStudent = { id: Math.random().toString(), Name: studentInput, }; setStudent([...student,newStudent]); setStudentInput(''); } }; const deleteStudent = (studentId) => { const newStudent = student.filter(item => item.id !== studentId); setStudent(newStudent); }; return ( <View style={styles.container}> <TouchableOpacity onPress={()=> navigation.goBack()} style={styles.button}> <Text>Back</Text> </TouchableOpacity> <Text style={{fontWeight: 'bold', fontSize: 20}}>{route.params.Classroom}</Text> <TextInput style={styles.input} placeholder={'Add Student Name'} value={studentInput} onChangeText={(text) => setStudentInput(text)} /> <TouchableOpacity onPress={()=> addStudent()} style={styles.button}> <Text>Add Student</Text> </TouchableOpacity> <FlatList style={styles.flatlist} data={student} keyExtractor = { (item) => item.id.toString() } renderItem={({ item }) => ( <View style={styles.listItem}> <View> <Text style={{fontSize: 18}}> {item?.Name} </Text> </View> <View > <TouchableOpacity style={[styles.delete ]} onPress={() => deleteStudent(item?.id)}> <Icon name="remove" size={15} color={'#fff'} /> </TouchableOpacity> </View> </View> )} /> </View> ); }; export default Classroom; const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', justifyContent: 'center', backgroundColor: '#ecf0f1', padding: 8, }, input: { width: '70%', borderBottomWidth: 1, marginBottom: 20, }, button: { backgroundColor: 'lightblue', padding: 10, marginBottom: 10, }, listItem: { flexDirection: 'row', justifyContent: 'space-between', width: '70%', alignItems: 'center', }, delete: { backgroundColor: '#ff3333', padding: 5, color: '#fff', borderWidth: 1, borderColor: '#ff9999', borderRadius: 5, }, });
内容的提问来源于stack exchange,提问作者BunnyHOPE
相关产品推荐
相关产品推荐

