在 AsyncStorage 中反应本机密钥

React Native key in AsyncStorage

我是 React Native 的新手,我想在我的项目中应用 AsyncStorage。我正在做一个项目,我可以在平面列表中添加教室,然后在每个教室中,我可以使用平面列表添加每个 class 的学生姓名。异步存储将应用于课堂列表和学生列表。

我的期望是,我添加classroom A,classroom B和classroom C,然后当我按Clasroom A时,我可以添加学生的名字和当我去 classB 房间时,名单仍然是空的,等待我填写名单。

我的实际结果是,我在classA房添加studentA,studentB,studentC后,当我去classB房时,classA房的3个学生class房间 B 的列表中仍然可用。

那么,我该如何解决这个问题才能满足我的要求,或者如果您能提供带有解释的代码,那将非常有帮助,我们将不胜感激。非常感谢您

这是我的 MainMenu.js 代码,我需要在其中添加 class 房间 :

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,
      },
  });

您的问题是您为所有学生设置了相同的密钥 student

如果您的 class 名称是唯一的,您需要做的是使用 class 名称为您的存储设置动态密钥,否则您需要使用 uuid 之类的东西来创建classes.

的唯一 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 这是不可能的。