【问题标题】:React Native Flatlist item navigate to new pageReact Native Flatlist 项目导航到新页面
【发布时间】:2021-09-18 16:56:07
【问题描述】:

我正在尝试制作一个可以在 flatlist 中添加项目的应用程序。然后每个项目我只能导航到该特定项目的新页面。在该页面中,我可以添加另一个平面列表。

为了更详细地解释它,假设我在平面列表中添加了一些课堂项目(课堂 A、课堂 B、课堂 C)。当我按 Clasroom A 时,它将导航到名为 Classroom A 的页面。在该页面中,我可以使用另一个平面列表添加和删除每个学生的姓名。

如何设计教室页面???因为当我在 A 教室添加学生姓名时,其他教室的平面列表中也会显示学生姓名。

这是我的主菜单代码:

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';

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 style={[styles.classText , {fontSize: 18}]}>
            {item?.Classroom}
              </Text>
            </View>
            <View >
              <TouchableOpacity style={[styles.delete ]} onPress={() => deleteClassroom(classroom?.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',
  },
});

这是教室的代码:

/* eslint-disable prettier/prettier */
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';


const Classroom = ( {navigation, route}) => {
    const [studentInput, setStudentInput] = useState('');
    const [student, setStudent] = useState([]);

    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}}>[ Classroom Name ]</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,
      },
  });

【问题讨论】:

  • Wdym "如何为教室创建页面"?您需要帮助设计它吗?请分享现有代码,并告诉我们哪些地方没有像您预期的那样工作。请阅读:stackoverflow.com/help/how-to-ask
  • 对不起@Elias。我已经在上面的问题中更新了我的代码。假设我在教室 A 中添加学生姓名詹姆斯,当我想添加教室 B 的学生列表时,詹姆斯也在里面。实际上,他不应该在 B 教室,因为他在 A 教室。还有,我怎样才能得到 Params 教室的名字?因为我得到并且错误 getParam is not a function.

标签: reactjs react-native react-native-flatlist react-native-navigation


【解决方案1】:

无论您在看哪个教室,您都使用相同的AsyncStorage'student'。您需要将您的学生列表分开,因此您需要为每个列表设置一个单独的密钥。比如:

const key = `students_in_room_${classroomId}`

您可以通过导航中的route 属性获取教室 ID(A、B、C)。


编辑:您将使用这个唯一的key 而不是字符串'students' 来读取和写入AsyncStorage。这样您就可以为每个教室分别存储值。

const students = await AsyncStorage.getItem(key);
await AsyncStorage.setItem(key, stringifyStudent);

【讨论】:

  • 你能详细解释一下 const 键吗?我不知道如何在我的代码中实现它。稍后将关键常量放在平面列表中还是放在哪里?并感谢您的路线道具。我设法将教室名称作为页面标题。
猜你喜欢
  • 1970-01-01
  • 2019-03-13
  • 2021-04-27
  • 1970-01-01
  • 2020-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-17
相关资源
最近更新 更多