![](/img/trans.png)
[英]Can't perform a React state update on an unmounted component with useEffect hook
[英]Can't perform a React state update on an unmounted component useEffect error
我有这段代码,我在其中获取数据并将其传递给组件。 然后这个子组件渲染我制作的数据,这样当用户从顶部下拉时,组件会刷新,但是每当我first time only
刷新时,我都会收到错误
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.
这是代码:
function FolloweringScreens({
data,
screen,
username,
navigation,
noMoreData,
setLoadingMore,
lastVisible,
setNoMoreData,
setLastVisible,
setfollowingData,
loadingMore,
setLoading,
currentuser,
}) {
const [stateData, setStateData] = useState();
const [refresh, setRefresh] = useState(false);
useEffect(() => {
const setState = () => setStateData(data);
return setState();
}, [data, refresh]);
// Refresh
const handleFetch = () => {
setRefresh(true);
const cleanup = fetchData(
username,
setfollowingData,
setLoading,
setLastVisible,
setNoMoreData,
setRefresh,
screen,
currentuser,
);
return cleanup;
};
return (
<>
<FlatList
refreshing={refresh}
onRefresh={handleFetch}
data={stateData}
keyExtractor={(i, index) => index.toString()}
renderItem={({item, index}) => {
return (
<>
{ Using my data here }
</>
);
}}
/>
</>
);
}
export default FolloweringScreens;
这是 fetchData function:
export const fetchData = (
username,
setfollowingData,
setLoading,
setLastVisible,
setNoMoreData,
setRefresh,
screen,
currentuser,
) => {
const dataaRef = firestore().collection('usernames');
setNoMoreData && setNoMoreData(false);
// If in
dataaRef // Go to whichever users clicked on data
.doc(username.toLowerCase())
.collection(screen) // Go to followers/following
.orderBy('followedAt')
.limit(6)
.get()
.then((snapshot) => {
setLoading(true);
snapshot.empty
? null
: setLastVisible(
snapshot.docs[snapshot.docs.length - 1].data().followedAt,
);
let promises = [];
// 1b. For each document, return that document data
snapshot.forEach((doc) => {
const data = doc.data();
promises.push(
data.path.get().then((res) => {
const userData = res.data();
// Go to logged in users directory to see
// if they are following these users in this
// users following/followers page so we can
// differentiate whether to display follow/unfollow button
return dataaRef
.doc(
currentuser === undefined
? username.toLowerCase()
: currentuser.toLowerCase(),
)
.collection('Following')
.doc(doc.id)
.get()
.then((searchedDocs) => {
return {
profileName: doc.id ? doc.id : null,
displayName: userData.displayName
? userData.displayName
: null,
followerCount:
userData.followers !== undefined ? userData.followers : 0,
followingCount:
userData.following !== undefined ? userData.following : 0,
imageUrl: userData.imageUrl ? userData.imageUrl : null,
isFollowed: searchedDocs.exists ? true : false,
};
});
}),
);
});
// 1c. set All document data to followingData
Promise.all(promises).then((res) => {
setfollowingData(res);
// console.log('res', res);
});
setLoading(false);
setRefresh && setRefresh(false);
});
};
你实际上不能那样做。 由于从 useEffect 返回的 function 充当清理 function。 您通常会清理您的背部,例如在组件处置时移除事件侦听器等。
useEffect(() => {
document.addEventListenter('click', () => {});
function cleanup() {
document.removeEventListener('click', () => {});
};
return cleanup;
})
这就是 useEffect 的工作原理。 因此,在您的情况下,当组件被卸载时,它抱怨 state 更新,这在反应世界中是非法的。
如果您想调用它,只需调用它。
useEffect(() => {
const setState = () => setStateData(data);
setState();
}, [data, refresh]);
或者更好的方法是在 useEffect 之外定义您的 function,并在其中调用它。
const setState = () => setStateData(data);
useEffect(() => {
if (!data) return;
setState();
}, [data, refresh]);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.