Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
106 views
in Technique[技术] by (71.8m points)

javascript - Props is undefined and not displaying proper profile page

So I'm building an app similar to Instagram with react-native, and currently, I have a problem where I search for a user (in this case, it's a test user), but the incorrect profile page is displayed. Specifically, every time I tap on a user, I'm navigated to the profile page of the current user logged in, not to another user's profile.

I believe this is because of an undefined props variable I pass into my search function but I have no idea why it's undefined or how to fix this issue. If anyone can help, that would be greatly appreciated.

Here's my code, I believe I've located the error across 3 different files, but I can upload more if necessary:

Main.js

import React, { Component } from 'react'
import { View, Text } from 'react-native';
import { createMaterialBottomTabNavigator } from '@react-navigation/material-bottom-tabs';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'
import firebase from 'firebase'

import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { fetchUser, fetchUserPosts } from '../redux/actions/index'

import Feed from './main/Feed'
import Profile from './main/ProfilePage';
import Search from './main/SearchUser';

const Tab = createMaterialBottomTabNavigator();

const EmptyScreen = () => {
    return(null)
}

export class Main extends Component {
    componentDidMount(){
        // Call upon the 'fetchUser' function in the actions folder which will access User.js and update the state of the user
        this.props.fetchUser();
        this.props.fetchUserPosts();

    }
    render() {
        return (
            <Tab.Navigator initialRouteName="Feed" labeled={false}>
                <Tab.Screen name="Feed" component={Feed} 
                options={{
                    tabBarIcon: ({ color, size }) => (
                        <MaterialCommunityIcons name="home" color={color} size={26}/>   
                    ),

                }}/>

                <Tab.Screen name="Search" component={Search} navigation={this.props.navigation} // <- Another potential source of error
                options={{
                    tabBarIcon: ({ color, size }) => (
                        <MaterialCommunityIcons name="magnify" color={color} size={26}/>   
                    ),

                }}/>

                <Tab.Screen name="AddContent" component={EmptyScreen}
                listeners={({ navigation }) =>({
                    tabPress: event => {
                        event.preventDefault();
                        navigation.navigate("Add")
                    }})}
                options={{
                    tabBarIcon: ({ color, size }) => (
                        <MaterialCommunityIcons name="plus-box" color={color} size={26}/>   
                    ),

                }}/>

                <Tab.Screen name="Profile" component={Profile} 
                listeners={({ navigation }) =>({
                    tabPress: event => {
                        event.preventDefault();
                        console.log("ProfilePage.js: " + firebase.auth().currentUser.uid)
                        navigation.navigate("Profile", {uid: firebase.auth().currentUser.uid})
                    }})}

                options={{
                    tabBarIcon: ({ color, size }) => (
                        <MaterialCommunityIcons name="account-circle" color={color} size={26}/>   
                    ),

                }}/>
            </Tab.Navigator>
        )
    }
}

const mapStateToProps = (store) => ({
    currentUser: store.userState.currentUser
})

// Connect function to props
const mapDispatchToProps = (dispatch) => bindActionCreators({fetchUser, fetchUserPosts}, dispatch);

export default connect(mapStateToProps, mapDispatchToProps)(Main);

SearchUser.js:

import React, { useState } from 'react'
import { View, Text, TextInput, FlatList, TouchableOpacity } from 'react-native'
import firebase from 'firebase'
require('firebase/firestore')

export default function Search(props) {
    const [users , setUsers] = useState([])
    
    const fetchUsers = (searchString) => {
        firebase.firestore()
        .collection("users")
        .where('name', '>=', searchString)
        .get()
        .then((result) => {
            let users = result.docs.map(doc => {
                const data = doc.data();
                const dataID = doc.id;
                return { dataID, ...data }
            });
            setUsers(users);
        })
    }

    return (
        <View>
            <TextInput placeholder="Type Here..."  onChangeText={(searchQuery) => fetchUsers(searchQuery)}/>
            <FlatList
                numColumns={1}
                horizontal={false}
                data={users}
                renderItem={({ item }) => (
                    <TouchableOpacity
                        onPress={() => props.navigation.navigate("Profile", {uid: item.id})} // <- Where I believe props is undefined
                    >
                        <Text>{item.name}</Text>
                    </TouchableOpacity>
                )}
            />
        </View>
    )
}

ProfilePage.js

import React, { useState, useEffect } from 'react'
// 'FlatList' allows for a grid-like display of the user's images
import { StyleSheet, View, Text, Image, FlatList } from 'react-native'

import firebase from 'firebase'
require('firebase/firestore')
import { connect } from 'react-redux'

// Display profile page
function Profile(props) {
    const [userPosts, setUserPosts] = useState([]);
    const [user, setUser] = useState(null);

    useEffect(() => {
        const { currentUser, posts } = props;
        console.log(props.route.params.uid)
        console.log(firebase.auth().currentUser.uid)
        if(props.route.params.uid === firebase.auth().currentUser.uid){
            setUser(currentUser)
            setUserPosts(posts)
        } else {
            firebase.firestore()
            .collection("users")
            .doc(props.route.params.uid)
            .get()
            .then((result) => {
                if(result.exists){
                    setUser(result.data());
                } else {
                    console.log('User is not in database or something has gone wrong') // <- This code activates
                }
            })

            firebase.firestore()
            .collection("posts")
            .doc(props.route.params.uid)
            .collection("userPosts")
            .orderBy("creation", "asc")
            .get()
            .then((result) => {
                // Build an array of posts by iterating over the results object and appending relevant data
                let posts = result.docs.map(doc => {
                    const data = doc.data();
                    const dataID = doc.id;
                    return { dataID, ...data }
                })
                setUserPosts(posts);
            })

        }

    }, [props.route.params.uid])

    if(user === null){
        return <View/>
    }
    return (
        <View style={styles.container}>
            <View style={styles.infoContainer}>
                <Text>{user.name}</Text>
                <Text>{user.email}</Text>
            </View>
            <View style={styles.galleryContainer}>
                {/* This view will handle the grid-like display of user's posts */}
                <FlatList
                    numColumns={3}
                    horizontal={false}
                    data={userPosts}
                    renderItem={({item}) => (
                        <View
                            style={styles.containerImage}
                        >
                            <Image
                                style={styles.image}
                                source={{uri: item.downloadURL}}
                            />
                        </View>
                    )}
                />
            </View>
        </View>
    )
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
    },

    infoContainer: {
        margin: 20,
    },

    galleryContainer: {
        flex: 1
    },

    containerImage: {
        flex: 1/3
    },

    image: {
        flex: 1,
        aspectRatio: 1/1
    }
})

const mapStateToProps = (store) => ({
    currentUser: store.userState.currentUser,
    posts: store.userState.posts
})

export default connect(mapStateToProps, null)(Profile);
question from:https://stackoverflow.com/questions/65931370/props-is-undefined-and-not-displaying-proper-profile-page

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...