FlatList does not rerender even if state assigned to extraData changes

╄→гoц情女王★ 提交于 2021-01-07 01:34:40

问题


I am building a Instagram clone backed by firebase and redux. I have a Profile screen in which i render the posts that the user has made. The problem with this is the posts does not get updated, I was using FlatList component and found that we need to use a extraData prop.

This is my Profile.tsx (Profile screen) :

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);

Here I am using the refresh state that changes whenever the posts changes, but the flatlist does not get updated.

NOTE : I can see in the console that posts are being updated and the refresh state too, so I expect that the flatlist gets re-rendered with new posts but that does not happen.

I have gone through all the other SO questions but couldn't find them useful because all of them are in class components.

来源:https://stackoverflow.com/questions/65547030/flatlist-does-not-rerender-even-if-state-assigned-to-extradata-changes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!