route.params не проходит должным образом в моем приложении React. js - PullRequest
0 голосов
/ 17 июня 2020

Я пытаюсь понять, почему мое приложение не работает должным образом. Основная предпосылка c состоит в том, что пользователь может выбирать различные типы карточек, которые он хочет просмотреть. Они разбиты на различные типы и выбираются с помощью флажков. Затем этот массив настроек передается на другой экран, где я беру свои данные из firebase и конвертирую их в массив. Затем эти массивы сравниваются друг с другом, и, если соблюдаются правильные критерии, они добавляются в новую колоду. Затем эта новая колода визуализируется и перемещается с помощью кнопок «Назад» и «Далее». Любая помощь будет принята с благодарностью.

Моя текущая ошибка говорит о том, что длина не определена, потому что при построении колоды мне нужно go через начальную колоду карт (массив firebase).

Current error:
×
TypeError: Cannot read property 'length' of undefined
buildDeck
C:/Users/Langley/Desktop/ArticCards/screens/CardScreen.js:39
  36 |    let deck = new Array();
  37 | 
  38 |    for(var i = 0; i < passDeck.length; i++){
> 39 |        for(var j = 0; j < currentSettings.length; j++){
     | ^  40 |            if((passDeck.cType[i] == currentSettings[j].arType) && (currentSettings[j].addCV == true)){
  41 |                deck.push(passDeck[i]);
  42 |            }

Главный экран

import React, { useState, useEffect } from "react";
import { StyleSheet, Text, Keyboard, TouchableOpacity, View, TouchableWithoutFeedback, Image } from "react-native";
import { Button } from "react-native-elements";
import { Feather } from "@expo/vector-icons";
import { initArticDB, setupArticListener } from '../helpers/fb-settings';


const HomeScreen = ({route, navigation}) => {
  const [ deck, setDeck] = useState([]);

  useEffect(() => {
    try {
      initArticDB();
    } catch (err) {
      console.log(err);
    }
    setupArticListener((items) => {
      setDeck(items);
    });
  }, []);

  useEffect(() => {
    if(route.params?.articCard){
      setCard({imageUrl: state.imageUrl, word: state.word, aType: state.aType, cType: state.cType, mastery: state.mastery})
    }
    if(route.params?.deck){
      setDeck({imageUrl: state.imageUrl, word: state.word, aType: state.aType, cType: state.cType, mastery: state.mastery})
    }
    if(route.params?.articType){
      setArticType({arType: state.arType, addCV: state.addCV})
    }
  }, [route.params?.articType, route.params?.deckeck, route.params?.articCard] );


  navigation.setOptions({
        headerRight: () => (
          <TouchableOpacity
            onPress={() =>
              navigation.navigate('Settings')
            }
          >
            <Feather
              style={styles.headerButton}
              name="settings"
              size={24}
              color="#fff"
            />
          </TouchableOpacity>
        ),
        headerLeft: () => (
          <TouchableOpacity
            onPress={() =>
              navigation.navigate('About')
            }
          >
            <Text style={styles.headerButton}> About </Text>
          </TouchableOpacity>
        ),
      });

    return(
      <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
        <View style={styles.container}>
          <Text style={styles.textmenu}>Welcome to Artic Cards</Text>
          <Text style={styles.textsubmenu}>Press Start to Begin!</Text>
          <Image source={require('../assets/5-snowflake-png-image.png')}
            style={{width: 300, height: 300, alignSelf: 'center'}}/>
          <Button
            title="Start"
            style={styles.buttons}
            onPress={() => navigation.navigate('Cards',
            {passDeck: deck})}
          />
          <Button
            title="Progress"
            style={styles.buttons}
            onPress={() => navigation.navigate('Progress')}
          />
          <Button
            title="Customize"
            style={styles.buttons}
            onPress={() => navigation.navigate('Customize')}
          />
        </View>
      </TouchableWithoutFeedback>
    );
};

const styles = StyleSheet.create({
  container: {
    padding: 10,
    backgroundColor: '#E8EAF6',
    flex: 1,
    justifyContent: 'center'
  },
  textmenu: {
    textAlign: 'center',
    fontSize: 30
  },
  textsubmenu:{
    textAlign: 'center',
    fontSize: 15
  },
  headerButton: {
    color: '#fff',
    fontWeight: 'bold',
    margin: 10,
  },
  buttons: {
    padding: 10,
  },
  inputError: {
    color: 'red',
  },
  input: {
    padding: 10,
  },
  resultsGrid: {
    borderColor: '#000',
    borderWidth: 1,
  },
  resultsRow: {
    flexDirection: 'row',
    borderColor: '#000',
    borderBottomWidth: 1,
  },
  resultsLabelContainer: {
    borderRightWidth: 1,
    borderRightColor: '#000',
    flex: 1,
  },
  resultsLabelText: {
    fontWeight: 'bold',
    fontSize: 20,
    padding: 10,
  },
  resultsValueText: {
    fontWeight: 'bold',
    fontSize: 20,
    flex: 1,
    padding: 10,
  },
});

export default HomeScreen;

Экран настроек

import React, {useState, useEffect} from 'react';
import {StyleSheet, TouchableOpacity, View} from "react-native";
import {Text, CheckBox} from "react-native-elements";
import {FlatList } from "react-native-gesture-handler";
//this is broken some how can't figure out why.

const SettingsScreen = ({route, navigation}) =>{
        //create a screen with checkbox fields. One for the consonant-vowel field and the other for the alphabet.
        //Both of which will be using flatlists preferably side by side
        //A card will only be counted if it meets both values being marked true (category and alpha)
    const [articType, setArticType] = useState([
        {arType: 'CV', addCV: true},
        {arType: 'VC', addCV: true},
        {arType: 'VV', addCV: true},
        {arType: 'VCV', addCV: true},
        {arType: 'CVCV', addCV: true},
        {arType: 'C1V1C1V2', addCV: true},
        {arType: 'C1V1C2V2', addCV: true},
    ]);



    navigation.setOptions({
        headerRight: () => (
            <TouchableOpacity onPress={() => navigation.navigate('Home')}>
            <Text style={styles.headerButton}> Cancel </Text>
            </TouchableOpacity>
        ),
        headerLeft: () => (
            <TouchableOpacity
            onPress={() => {
                // navigate back with new settings.
                navigation.navigate('Home', {
                    currentSetting: articType
                });
            }}
            >
            <Text style={styles.headerButton}> Save </Text>
            </TouchableOpacity>
        ),
    });    

    const renderCVType = ({index, item}) =>{

        return(
            <CheckBox
                title={item.arType}
                checked={item.addCV}
                onPress={() => {
                    let newArr = [... articType];
                    newArr[index] = {...item, addCV: !item.addCV};
                    setArticType(newArr);
                    console.log(newArr);
                }}
            />
        )
    }

    return(
        <View style={styles.container}>
            <Text style={styles.textmenu}>Artic Type</Text>
            <Text style={styles.textsubmenu}>Select what words to include based on their cononants and vowels</Text>
            <FlatList  
                keyExtractor={(item) => item.arType}
                data={articType}
                renderItem={renderCVType}
            />

        </View>
    )

}


const styles = StyleSheet.create({
    container: {
      padding: 10,
      backgroundColor: '#E8EAF6',
      flex: 1,
    },
    textmenu: {
      textAlign: 'center',
      fontSize: 30
    },
    textsubmenu:{
      textAlign: 'center',
      fontSize: 15
    },
});

export default SettingsScreen;

Экран карты

import React, { useState, useRef,   useEffect } from "react";
import { StyleSheet, Text, View } from "react-native";
import { Button, Card } from "react-native-elements";
import { updateArtic } from "../helpers/fb-settings";
import { State } from "react-native-gesture-handler";
//Cannot navigate to this page, not sure why

//general formatting and importing of the deck. Probably put shuffle function here with imported array
//Next and previous buttons should bascially refresh page and give next or previous card
//mastery probably will require setupArticListener (this needs clarification though)
//Deck will be imported here and the information from SettingScreen will be imported here as well
const CardScreen = ({route, navigation}) =>{

    const { currentSettings, passDeck } = route.params;
    const renderCard = ({index, item}) => {
        <View>
            <Card
            title={item.word}
            image={{uri: item.imageUrl}}>
                <Text> {item.cType} </Text>
            </Card>
        </View>
    }
    const renderMastery = ({index, item}) =>{
        return(
            <CheckBox
                title={'Mastered?'}
                checked={!item.mastery}
                onPress={() => {
                    updateArtic({ ...item, mastery: !item.mastery });
                }}
            />
        )
    }
    function buildDeck(){
        let deck = new Array();

        for(var i = 0; i < passDeck.length; i++){
            for(var j = 0; j < currentSettings.length; j++){
                if((passDeck.cType[i] == currentSettings[j].arType) && (currentSettings[j].addCV == true)){
                    deck.push(passDeck[i]);
                }
            }
        }
        return deck;
    }

    function nextCard(){
        var k = deck.indexOf();

        if( (k+1) <= deck.length){
            return deck[k+1];
        } else{
            return deck[0];
        }

    }

    function previousCard(){
        var k = deck.indexOf();

        if( (k-1) >= 0){
            return deck[k-1];
        } else{
            return deck[(deck.length - 1)];
        }
    }

    buildDeck();

    return(
        <View>
            <Text>Cards</Text>
            {renderCard(deck)}
            <View style={styles.row}>
                <Button
                    title='Next'
                    onPress={
                        nextCard()
                    }
                />
                renderItem{renderMastery}
                <Button
                    title='Previous'
                    onPress = {
                        previousCard()
                    }
                />
            </View>
        </View>
    )
}

const styles= StyleSheet.create({
    row: {
        flexDirection: 'row',
        flex: 1,
        marginBottom: 1
    },

})

export default CardScreen;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...