我正在构建一个由 firebase 和 redux 支持的 Instagram 克隆。我有一个个人资料屏幕,我在其中呈现用户发表的帖子。问题是帖子没有更新,我在使用 FlatList
组件,发现我们需要使用 extraData
道具。
这是我的Profile.tsx(个人资料屏幕):
import React, { useState, useEffect } from "react";
import { View, Text, StyleSheet, Image, FlatList, Alert } from "react-native";
import db, { auth } from "../../firebase";
import { Avatar, Button, ActivityIndicator, Colors } from "react-native-paper";
import Navbar from "../shared/Navbar";
import { connect } from "react-redux";
import { FontAwesome5 } from "@expo/vector-icons";
const Profile = ({
navigation,
posts,
route,
reduxFollowing,
currentUser,
}: any) => {
const [user, setUser] = useState<any>(null);
const [userPosts, setUserPosts] = useState<any>([]);
const [loading, setLoading] = useState<boolean>(true);
const [following, setFollowing] = useState<boolean>(false);
const [refresh, setRefresh] = useState<boolean>(false);
useEffect(() => {
if (route.params.uid === auth.currentUser?.uid) {
setUser(auth.currentUser);
setUserPosts(posts);
setLoading(false);
} else {
db.collection("users")
.doc(route.params?.uid)
.get()
.then((snapshot) => {
setLoading(false);
if (snapshot.exists) {
setUser(snapshot.data());
} else {
console.log("does not exist");
}
});
db.collection("posts")
.doc(route.params.uid)
.collection("userPosts")
.orderBy("creation", "desc")
.onSnapshot((snapshot) => {
let posts = snapshot.docs.map((doc) => {
const data = doc.data();
const id = doc.id;
return { ...data, id };
});
setUserPosts(posts);
setRefresh(!refresh);
});
if (reduxFollowing.indexOf(route.params.uid) > -1) {
setFollowing(true);
} else {
setFollowing(false);
}
}
}, [route.params.uid, reduxFollowing]);
useEffect(() => {
setRefresh(!refresh);
}, [posts]);
const onFollow = () => {
db.collection("following")
.doc(auth.currentUser?.uid)
.collection("userFollowing")
.doc(route.params.uid)
.set({})
.then(() => setFollowing(true))
.catch((err) =>
Alert.alert("Opps!, could not Login", err.message, [{ text: "Ok" }])
);
};
const onUnfollow = () => {
db.collection("following")
.doc(auth.currentUser?.uid)
.collection("userFollowing")
.doc(route.params.uid)
.delete()
.then(() => setFollowing(false))
.catch((err) =>
Alert.alert("Opps!, could not Login", err.message, [{ text: "Ok" }])
);
};
if (loading) {
return (
<View style={styles.loading}>
<ActivityIndicator size={60} color={Colors.blue500} />
</View>
);
}
console.log(posts);
const TwoBtn = () => (
<>
{following ? (
<Button
style={styles.btn}
uppercase={false}
mode="outlined"
color={Colors.green500}
onPress={onUnfollow}
>
Following
</Button>
) : (
<Button
style={styles.btn}
uppercase={false}
mode="outlined"
color="black"
onPress={onFollow}
>
Follow
</Button>
)}
<Button
style={styles.btn}
uppercase={false}
mode="outlined"
color="black"
onPress={() => navigation.navigate("Chat")}
>
Chat
</Button>
</>
);
const OneBtn = () => (
<Button
style={styles.btn2}
uppercase={false}
mode="outlined"
color="black"
onPress={() => navigation.navigate("EditProfile", { user })}
>
Edit Profile
</Button>
);
const imgSrc = user?.photoURL;
console.log(refresh);
return (
<View style={styles.container}>
<Navbar
navigation={navigation}
title={auth.currentUser?.displayName || currentUser.name}
/>
<View style={styles.topContainer}>
{imgSrc ? (
<Avatar.Image source={{ uri: imgSrc }} />
) : (
<FontAwesome5 name="user-circle" size={60} color="black" />
)}
<View style={styles.topRightCont}>
<Text style={styles.label}>
Name :{" "}
<Text style={styles.text}>{user?.displayName || user?.name}</Text>
</Text>
<Text style={styles.label}>
Email : <Text style={styles.text}>{user?.email}</Text>
</Text>
</View>
</View>
{route.params.uid === auth.currentUser?.uid ? (
<View style={styles.btnCont}>
<OneBtn />
</View>
) : (
<View style={styles.btnCont}>
<TwoBtn />
</View>
)}
<View style={styles.galleryCont}>
<FlatList
keyExtractor={(item) => item?.id}
numColumns={3}
horizontal={false}
data={userPosts}
extraData={refresh}
renderItem={({ item }) => (
<Image style={styles.image} source={{ uri: item?.downloadURL }} />
)}
/>
</View>
</View>
);
};
const styles = StyleSheet.create({
//styles
});
const mapStateToProps = (store: any) => ({
currentUser: store.userState.currentUser,
posts: store.userState.posts,
reduxFollowing: store.userState.following,
});
export default connect(mapStateToProps, null)(Profile);
这里我使用的是 refresh
状态,该状态会在帖子更改时更改,但平面列表不会更新。
注意:
我可以在控制台中看到帖子正在更新,refresh
状态也是如此,所以我希望平面列表会用新帖子重新呈现,但不会发生这种情况。
我已经完成了所有其他 SO 问题,但没有发现它们有用,因为它们都在类组件中。