简体   繁体   中英

How to pass data from Class to function in React Native array, firebase, stack navigator v5

Hay I am struggling on how to pass data that's in a class, to another react native component. I am able to display data on the same screen, however I want to have the user input some text and have it display on another screen.

1) Initial Screen: User presses button to navigate to text inputs, and will navigate back to this screen to view the list. Note : If I add the list here I get an error " undefined is not an object ". Because I was not able to figure out how to PASS THE LISTARRAY variable to that screen.

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) List Screen: If I put the flatList here everything works, but I need to PASS THE DATA thats inputted here in the firebase real-time database and display it on the other screen shown above.



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>

        );
    }
}

I have tried to useState and pass data as a param but got errors, in able to use the variable navigation in a class..? Also tried to put it in a separate function and that did now work ether. I'll add my code bellow so you can take a look. Any suggestions and or references to any helpful docs would really be appreciated.

Would really appreciate some help, been trying to resolve this for the past few days with no luck. Many thanks!

If i understand the flow correctly, what you want is the following: Initially, you have a first screen with a list of items (GoalsScreen). From there the user can open a new screen, where he can add items (AddGoalScreen). So, when the user goes back, you want him to see the updated list.

First of all, in the above code, the GoalsSrceen has not defined any state listArray, so that's why you get undefined error. You need to declare it just like you did in AddGoalScreen. Also, as i can see, the AddGoalScreen will no longer display this listArray, so you can simply move the goalsRef.on('value', ... subscription in the GoalsScreen. Doing so, each time you push to the firebase through AddGoalScreen, the on('value') subscription will be triggered inside GoalsScreen, and the GoalsScreen will rerender, keeping its state available. So you have your problem fixed

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM