I am having an issue when I am trying to fetch some data. For some reason, I keep receiving this error:
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
This is the entire component, where I am fetching the data and then passing it in to the drawerconfig component This data then gets passed down further and further in to other components:
export default function Root() {
const [userImage, setUserImage] = useState();
const [userName, setUserName] = useState();
const [name, setName] = useState();
const [urlName, setUrlName] = useState();
const [userID, setUserID] = useState();
const [followerCount, setFollowerCount] = useState();
const [followingCount, setFollowingCount] = useState();
const [links, setLinks] = useState([{link: null}]);
const [pageLoading, setPageLoading] = useState(true);
// Following counts, displayname, image
const fetchData = useCallback((data) => {
const dataRef = firestore().collection('usernames');
const usersLinks = firestore().collection('links');
// Fetch user Links
usersLinks.doc(data.data().urlName).onSnapshot((doc) => {
const entries =
doc.data() === undefined ? [undefined] : Object.values(doc.data());
entries[0] === undefined ? setLinks([{link: null}]) : setLinks(entries);
});
dataRef.doc(data.data().urlName).onSnapshot((snap) => {
// Fetch users image
setUserImage(snap.data().imageUrl);
setUserID(snap.data().displayName);
setUserName(snap.data().userName);
setUrlName(data.data().urlName);
setName(snap.data().displayName);
setFollowerCount(snap.data().followers);
setFollowingCount(snap.data().following);
setPageLoading(false);
});
}, []);
// Fetch all data here
useEffect(() => {
auth().onAuthStateChanged((user) => {
if (user !== null) {
if (user.emailVerified) {
const cleanup = firestore()
.collection('users')
.doc(user.uid)
.onSnapshot(fetchData);
return cleanup;
}
}
});
}, [fetchData]);
return (
<>
{/* ALL SCREENS */}
{pageLoading ? (
<ActivityIndicator size="large" color="black" />
) : (
<DrawerConfig
links={links}
username={userName}
userimage={userImage}
userid={userID}
displayname={name}
urlname={urlName}
followerCount={followerCount}
followingCount={followingCount}
/>
)}
</>
);
}
Any help would be appreciated, Thank you
Looks like you need to modify your useEffect a bit - I don't think your listener is being unsubscribed when you unmount this component.
// Fetch all data here
useEffect(() => {
return auth().onAuthStateChanged((user) => {
...
})
})
.onAuthStateChanged() returns the unsubscribe function; useEffect accepts an unsubscribe function as a return to be executed on unmount.