我曾尝试在 mounted = useRef()
和 let mounted.current = true
的开头使用 useEffect
和 return () => mounted.current = false
,但仍然收到此错误消息:
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.
in NameDetails (at TitleRow.js:114)
in RCTView (at View.js:34)
in View (at TitleRow.js:113)
in titleRow (at TodayTitleList.js:154)
in RCTView (at View.js:34)
in View (at VirtualizedList.js:2015)
in VirtualizedListCellContextProvider (at VirtualizedList.js:2030)
in CellRenderer (at VirtualizedList.js:807)
in RCTScrollContentView (at ScrollView.js:1107)
in RCTScrollView (at ScrollView.js:1213)
in ScrollView (at ScrollView.js:1264)
in ScrollView (at VirtualizedList.js:1250)
in VirtualizedListContextProvider (at VirtualizedList.js:1080)
in VirtualizedList (at FlatList.js:620)
in FlatList (at TodayTitleList.js:149)
in RCTSafeAreaView (at SafeAreaView.js:51)
in SafeAreaView (at TodayTitleList.js:136)
查看堆栈跟踪,我猜测错误出在 NameDetails
文件中,并且涉及其中的 useEffect
。是这样吗?
以下是我的代码:
const NameDetails = ({ title }) => {
const [color, setColor] = useState('#000');
useEffect(() => {
//let mounted = true;
const getColor = async (id) => {
const chosenColor = await getColorFortitle(id);
setColor(chosenColor);
//return () => { mounted = false };
};
getColor(title.id);
});
return (
<View>
...
</View>
);
};
export default NameDetails;
更多信息:当我注销并尝试再次登录时会发生此错误,并且仅在某些时候发生。
答案 0 :(得分:0)
您正在使用 useEffect
每次重新渲染组件:
添加 empty dependency to useEffect
to run only on first render
const mounted = useRef(false);
useEffect(() => mounted.current = true, []);
useEffect(() => {
const getColor = async (id) => {
const chosenColor = await getColorFortitle(id);
setColor(chosenColor);
}
if(mounted.current)
getColor(title.id);
return () => { mounted.current = false };
}, []);
答案 1 :(得分:0)
请检查我的代码 希望对你有帮助。
const NameDetails = ({ title }) => {
const [color, setColor] = useState('#000');
const [mounted, setMount] = useState(true);
useEffect(() => {
const getColor = async (id) => {
const chosenColor = await getColorFortitle(id);
setColor(chosenColor);
return () => { setMount = false };
};
getColor(title.id);
});
return (
<View>
...
</View>
);
};
export default NameDetails;
我只使用一种状态。因此,您可以使用状态更改值。 运行您的代码。
答案 2 :(得分:0)
const NameDetails = ({ title }) => {
const [color, setColor] = useState('#000');
useEffect(() => {
let mounted = true;
const getColor = async (id) => {
const chosenColor = await getColorFortitle(id);
mounted && setColor(chosenColor);
};
getColor(title.id);
return () => { mounted = false };
}, [title.id]);
return (
<View>
...
</View>
);
};
更理想的方法:
const NameDetails = ({ title }) => {
const isMounted = React.useRef(true);
React.useEffect(() => () => (isMounted.current = false), []);
const [color, setColor] = useState('#000');
useEffect(() => {
const getColor = async (id) => {
const chosenColor = await getColorFortitle(id);
isMounted.current && setColor(chosenColor);
};
getColor(title.id);
}, [title.id]);
return (
<View>
...
</View>
);
};
或者,如果您不确定那里发生了什么,您可以尝试将我的库与基于生成器的异步钩子一起使用,这样您就不必担心卸载了:
import React, { useState } from "react";
import { useAsyncEffect } from "use-async-effect2";
const NameDetails = ({ title }) => {
const [color, setColor] = useState('#000');
useAsyncEffect(function*(){
const chosenColor = yield getColorFortitle(title.id);
setColor(chosenColor);
}, [title.id]);
return (
<View>
...
</View>
);
};