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