I have a react native app which I get the user from the firebase firestore database. This works properly. But when I try to get the followers length from the user object it doesn't show or change it only changes when I make a change in the code and the app refreshes.
I read somewhere that useEffect runs on the second frame so I tried putting the code outside the useEffect but nothing changes
const [followingLength, setFollowingLength] = useState(0);
const [followersLength, setFollowersLength] = useState(0);
useEffect(() => {
const userSub = onSnapshot(doc(firestore, "Users", userId), (doc) => {
setUser(doc.data())
if (user.following.length !== 0) {
setFollowingLength(user.following.length)
}
if (user.followers.length !== 0) {
setFollowersLength(user.followers.length)
}
});
});
<Text style={{ color: colors.white }}>{followingLength}</Text>
<Text style={{ color: colors.white }}>{followersLength}</Text>
CodePudding user response:
From the things I see definitelly:
Issue 1: Why your useEffect
does not have any dependency array
? In that case the code will be executed in every render which will be buggy and expensive.
Issue 2: Do you know that setUser
does not update user
object immediatelly and user
in your if
is "old" and closure captured?
Issue 3: Do you know that onSnapshot
returns unsubscribe
function that needs to be called to stop the listener. In your case you are adding 1 additional listener every render which is also buggy and expensive.
Im not 100% sure those combination of issues is exact the source of your problems, but they definitelly should be solved
Note: You can use useMemo
to calculate following and followers.
const [user, setUser] = useState();
const followingLength = useMemo(() => {
return user?.following?.length || 0;
}, [user]);
const followersLength = useMemo(() => {
return user?.followers?.length || 0;
}, [user]);
useEffect(() => {
const unsubscribe = onSnapshot(doc(firestore, "Users", userId), (doc) => {
setUser(doc.data());
// Or
// const u = doc.data();
// setUser(u);
// setWhateverElse from "u", not "user"
});
return unsubscribe;
}, [userId]);