Как передать данные из класса в функцию в массиве React Native, Firebase, стековом навигаторе v5 - PullRequest
0 голосов
/ 14 марта 2020

Хей, я изо всех сил пытаюсь передать данные, находящиеся в классе, в другой реагирующий нативный компонент. Я могу отображать данные на одном экране, однако я хочу, чтобы пользователь вводил какой-то текст и отображал его на другом экране.

1) Начальный экран: пользователь нажимает кнопку для перехода к вводу текста и возвращается к этому экрану для просмотра списка. Примечание : Если я добавлю сюда список, я получу ошибку " undefined не является объектом ". Потому что я не смог понять, как передать переменную LISTARRAY на этот экран.

export const GoalsScreen = ({ navigation }) => {

    return (
        <SafeAreaView style={styles.container}>
            <Header>
                {/* header title */}
                <Text style={styles.goalText}> Expand your life</Text>

                {/* add goal button goto stack */}
                <TouchableOpacity onPress={() => navigation.navigate("AddGoal")} >
                    <Text style={styles.addBtn}> + </Text>
                </TouchableOpacity>
            </Header>

            {/* Error here, need to get data from other screen */}
            <FlatList
                data={this.state.listArray}
                renderItem={({ item, index }) => {
                    return (
                        <View>
                            <Text style={{ fontSize: 30 }}>{item.fireListGoal} </Text>
                            <Text style={{ fontSize: 20 }}>{item.fireListCat}</Text>
                            <Text style={{ fontSize: 15 }}> {item.fireListWhy}</Text>
                        </View>
                    );
                }}
            >
            </FlatList>

        </SafeAreaView>
    );
}

2) Экран списка: если я поместил здесь flatList, все работает, но мне нужно ПРОЙДИТЬ ДАННЫЕ, которые введены здесь в базе данных реального времени Firebase и отобразить его на другом экране, показанном выше.



export class AddGoalList extends React.Component {

    // state and defult values
    constructor(props) {
        super(props)

        // set inital values
        this.state = {
            listArray: [],
            goal: '',
            category: 'Pick One',
            why: '',
        }
    }

    //triggers rerendering, put values in a JSON array
    componentDidMount() {
        goalsRef.on('value', (childSnapshot) => {
            const listArray = [];
            childSnapshot.forEach((doc) => {
                listArray.push({
                    key: doc.key,
                    fireListGoal: doc.toJSON().fireListGoal,
                    fireListCat: doc.toJSON().fireListCat,
                    fireListWhy: doc.toJSON().fireListWhy
                });
                this.setState({
                    listArray: listArray.sort((a, b) => {
                        return (
                            a.fireListGoal < b.fireListGoal,
                            a.fireListCat < b.fireListCat,
                            a.fireListWhy < b.fireListWhy
                        );

                    }),
                });
            });
        });
    }



    // when button pressed... 
    onGoal = ({ }) => {
        // if form empty alert user
        if (this.state.goal.trim() && this.state.why.trim() === '') {
            alert("Please fill form.");
            return;
        }
        if (this.state.category.valueOf() === 'Pick One') {
            alert("Fill in all inputs.");
            return;
        }
        // otherwise push data to firebase
        goalsRef.push({
            fireListGoal: this.state.goal,
            fireListCat: this.state.category,
            fireListWhy: this.state.why
        });
    }

    render() {

        return (
            // KeyboardAvoidingView ==> prevent keyboard from overlapping
            <KeyboardAvoidingView style={styles.container}>
                <SafeAreaView>
                    <Text>Sparks your life!</Text>

                    {/* Goal title */}
                    <Text>What is your goal</Text>

                    <TextInput
                        placeholder="Enter your goal"
                        keyboardType='default'
                        onChangeText={
                            (text) => {
                                this.setState({ goal: text });
                            }
                        }
                        value={this.state.goal}
                    />

                    {/* pick selected cetegory */}
                    <Text>Pick a Category</Text>
                    {/* picker component */}
                    <Picker
                        selectedValue={this.state.category}
                        onValueChange={(itemValue) => this.setState({ category: itemValue })}
                    >
                        <Picker.Item label="Pick One" value="Pick One" />
                        <Picker.Item label="Fitness" value="Fitness" />
                        <Picker.Item label="Health" value="Health" />
                        <Picker.Item label="Travel" value="Travel" />
                        <Picker.Item label="Wealth" value="Wealth" />
                        <Picker.Item label="Creativity" value="Creativity" />
                        <Picker.Item label="Skills" value="Skills" />

                    </Picker>

                    <Text>Why did you pick this goal?</Text>

                    <TextInput
                        placeholder="Enter your why"
                        keyboardType='default'
                        onChangeText={
                            (text) => {
                                this.setState({ why: text });
                            }
                        }
                        value={this.state.why}
                    />

                    {/* nav back to My Goal list */}
                    <Button title="add goal" onPress={this.onGoal.bind(this)} />
                </SafeAreaView>

                {/* remove list here and add to other GoalsScreen */}
                <FlatList
                    data={this.state.listArray}
                    renderItem={({ item, index }) => {
                        return (
                            <View> 
                                <Text style={{fontSize: 30}}>{item.fireListGoal} </Text>
                                <Text style={{fontSize: 20}}>{item.fireListCat}</Text>
                                <Text style={{fontSize: 15}}> {item.fireListWhy}</Text>
                            </View>
                        );
                    }}
                >
                </FlatList> 



            </KeyboardAvoidingView>

        );
    }
}

Я пытался использовать State и передавать данные в качестве параметра, но получил ошибки, из-за возможности использовать переменную навигацию в классе ..? Также попытался поместить его в отдельную функцию, и это теперь работает эфир. Я добавлю свой код ниже, чтобы вы могли посмотреть. Будем очень благодарны за любые предложения и ссылки на любые полезные документы.

Был бы очень признателен за помощь, пытаясь решить эту проблему в течение последних нескольких дней, но безуспешно. Большое спасибо!

1 Ответ

1 голос
/ 15 марта 2020

Если я правильно понимаю поток, вам нужно следующее: Изначально у вас есть первый экран со списком элементов (GoalsScreen). Оттуда пользователь может открыть новый экран, где он может добавлять элементы (AddGoalScreen). Итак, когда пользователь возвращается, вы хотите, чтобы он увидел обновленный список.

Прежде всего, в приведенном выше коде GoalsSrceen не определил никакого состояния listArray, поэтому вы получаете неопределенную ошибку. Вы должны объявить это так же, как вы сделали это в AddGoalScreen. Кроме того, как я вижу, AddGoalScreen больше не будет отображать этот listArray, поэтому вы можете просто переместить подписку goalsRef.on('value', ... в GoalsScreen. При этом каждый раз, когда вы отправляете sh в базу данных огня через AddGoalScreen, подписка on('value') будет активироваться внутри GoalsScreen, и GoalsScreen будет повторно отображаться, сохраняя свое состояние доступным. Итак, ваша проблема исправлена ​​

...