reactjs - 在 AsyncStorage 中反应本机键
问题描述
我是 React Native 的新手,我想在我的项目中应用 AsyncStorage。我正在做一个项目,我可以在平面列表中添加教室,然后在每个教室中,我可以使用平面列表添加每个班级的学生姓名。Asyncstorage 将应用于课堂列表和学生列表。
我的期望是,我添加教室 A ,教室 B 和教室 C ,然后当我按下教室 A 时,我可以添加学生的姓名,当我去教室 B 时,名单仍然是空的等我来填.
我的实际结果是,当我在 A 教室添加 studentA , studentB , studentC 后,当我去教室 B 时,教室 B 的列表中仍然有教室 A 的 3 个学生。
那么,我该如何解决这个问题以满足我的要求,或者如果您能提供带有解释的代码,那将非常有帮助和非常感激。非常感谢您提前
这是我需要添加教室的 MainMenu.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 { useNavigation } from '@react-navigation/native';
import { CardStyleInterpolators } from '@react-navigation/stack';
export default function MainMenu(){
const [classroomInput, setClassroomInput] = useState('');
const [classroom, setClassroom] = useState([]);
const navigation = useNavigation();
useEffect(() => {
getClassroom();
}, []);
useEffect(() => {
saveClassroom(classroom);
}, [classroom]);
const saveClassroom = async (classroom) => {
try {
const stringifyClassroom = JSON.stringify(classroom);
await AsyncStorage.setItem('classroom', stringifyClassroom);
} catch (error) {
console.log(error);
}
};
const getClassroom = async () => {
try {
const classrooms = await AsyncStorage.getItem('classroom');
if (classrooms !== null) {
setClassroom(JSON.parse(classrooms));
}
} catch (error) {
console.log(error);
}
};
const addClassroom = () => {
if (classroomInput === ''){
Alert.alert('Error', 'Please input class');
} else {
const newClassroom = {
id: Math.random().toString(),
Classroom: classroomInput,
};
setClassroom([...classroom,newClassroom]);
setClassroomInput('');
}
};
const deleteClassroom = (classroomId) => {
const newClassrooms = classroom.filter(item => item.id !== classroomId);
setClassroom(newClassrooms);
};
return (
<View style={styles.container}>
<TextInput
style={styles.input}
placeholder={'Add Classrooms'}
value={classroomInput}
onChangeText={(text) => setClassroomInput(text)}
/>
<TouchableOpacity onPress={() => addClassroom()} style={styles.button}>
<Text>Add Classroom</Text>
</TouchableOpacity>
<FlatList
style={styles.flatlist}
data={classroom}
keyExtractor = { (item) => item.id.toString() }
renderItem={({ item }) => (
<TouchableOpacity onPress= {() => navigation.navigate('Classroom', item)} >
<View style={styles.listItem}>
<View>
<Text>
{item?.Classroom}
</Text>
</View>
<View >
<TouchableOpacity style={[styles.delete ]} onPress={() => deleteClassroom(item?.id)}>
<Icon name="remove" size={15} color={'#fff'} />
</TouchableOpacity>
</View>
</View>
</TouchableOpacity>
)}
/>
</View>
);
}
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,
},
delete: {
backgroundColor: '#ff3333',
padding: 5,
color: '#fff',
borderWidth: 1,
borderColor: '#ff9999',
borderRadius: 5,
},
listItem: {
flexDirection: 'row',
justifyContent: 'space-between',
width: '70%',
alignItems: 'center',
},
});
这是 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();
useEffect(() => {
getStudent();
}, []);
useEffect(() => {
saveStudent(student);
}, [student]);
const saveStudent = async (student) => {
try {
const stringifyStudent = JSON.stringify(student);
await AsyncStorage.setItem('student', stringifyStudent);
} catch (error) {
console.log(error);
}
};
const getStudent = async () => {
try {
const students = await AsyncStorage.getItem('student');
if (students !== null) {
setStudent(JSON.parse(students));
}
} 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 styles={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={[styles.classText , {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,
},
});
解决方案
您的问题是您正在使用相同的 key 设置所有学生student
。
如果您的类名是唯一的,那么您需要做的是使用类名为您的存储设置动态键,否则您需要使用 uuid 之类的东西来为您的类创建唯一的 id。
例如,您可以在保存学生功能中执行此操作
const saveStudent = async (student) => {
try {
const stringifyStudent = JSON.stringify(student);
await AsyncStorage.setItem(`class${class.name}:students`, stringifyStudent);
} catch (error) {
console.log(error);
}
};
并为您的获取学生功能执行此操作
const getStudent = async () => {
try {
const students = await AsyncStorage.getItem(`class${class.name}:students`);
if (students !== null) {
setStudent(JSON.parse(students));
}
} catch (error) {
console.log(error);
}
};
还可以尝试使用 uuid 包而不是 Math.random 来创建 id。确实,使用 Math.random 获得相同的数字是非常不可能的,但它仍然是可能的,但使用 uuid 这是不可能的。
推荐阅读
- ruby-on-rails - 在 bash 脚本中找不到捆绑命令
- tensorflow - 每当从 Tensorflow-hub 加载模型时,Colab 内核都会重新启动
- go - 如何将持续时间分成两半
- javascript - OnChange 处理程序仅在组件的第一个实例中触发,即使它是在不同实例上触发的
- linux - 与 Cloudfront 集成的 Drupal 上的 Base64 图像重定向问题
- search - Sonarqube `analyzedBefore` 计数不匹配
- excel - 打开电子表格并自动输入链接电子表格的密码
- python - 如何从设定的日期仅获取 7 天的数据?
- javascript - 没有重载匹配此调用。类型“字符串”不可分配给类型“信号”
- android - 收到错误“智能转换为 'EditText!' 是不可能的,因为 'usernameET' 是一个可变属性,此时可能已更改”