【问题标题】:React Native key in AsyncStorage在 AsyncStorage 中反应本机键
【发布时间】:2021-09-19 17:53:42
【问题描述】:

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

【问题讨论】:

    标签: reactjs react-native react-native-android react-native-flatlist asyncstorage


    【解决方案1】:

    您的问题是您正在使用相同的密钥 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 这是不可能的。

    【讨论】:

    • 好的,我会尝试使用 uuid 创建 id。对于 AsyncStorage 。你能解释更多关于class${class.name}: students 的信息吗?因为我在 {class.name} 中的类是未定义的,这是我第一次看到像 class${class.name} : students 这样的 AsyncStorage 代码
    • 你可以使用 route.params.id 代替 class.id
    猜你喜欢
    • 2017-01-13
    • 1970-01-01
    • 2020-02-21
    • 2021-12-07
    • 1970-01-01
    • 2021-10-20
    • 2021-09-28
    • 1970-01-01
    • 2021-10-04
    相关资源
    最近更新 更多