![](/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.