[英]How to useEffect cleanup function in react native?
Warning: Can't perform a React state update on an unmounted component.警告:无法对未安装的组件执行 React state 更新。 This is a no-op, but it indicates a memory leak in your application.
这是一个无操作,但它表明您的应用程序中存在 memory 泄漏。 To fix, cancel all subscriptions and asynchronous tasks in %s.%s, a useEffect cleanup function,
要修复,请取消 %s.%s 中的所有订阅和异步任务,useEffect 清理 function,
const Drawer = createDrawerNavigator();
const App = () => {
const [isLoading, setIsLoading] = React.useState(true);
const [userToken, setUserToken] = React.useState(null);
const authContext = React.useMemo(() => ({
SignIn: () => {
setUserToken('qwertyuiop');
setIsLoading(false);
},
SignOut: () => {
setUserToken(null);
setIsLoading(false);
},
SignUp: () => {
setUserToken('qwe');
setIsLoading(false);
},
}));
useEffect(() => {
setTimeout(() => {
setIsLoading(false);
}, 1000);
}, []);
if (isLoading) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<ActivityIndicator size="large" />
</View>
);
}
console.log("userToken", userToken)
console.log("authContext", authContext)
return (
<AuthContext.Provider value={authContext}>
<NavigationContainer>
{userToken !== null ? (
<Drawer.Navigator drawerContent={props => <DrawerContent {...props} />}>
<Drawer.Screen name="HomeDrawer" component={MainTabScreen} />
<Drawer.Screen name="Support" component={SupportScreen} />
<Drawer.Screen name="Setting" component={SettingScreen} />
<Drawer.Screen name="Bookmark" component={BookmarkScreen} />
</Drawer.Navigator>
)
:
<RootStackScreen />
}
</NavigationContainer>
</AuthContext.Provider>
);
}
You should always clear setTimeout
s setInterval
s on unmount.您应该始终在卸载时清除
setTimeout
s setInterval
s。
useEffect(() => {
const timeout = setTimeout(() => {
setIsLoading(false);
}, 1000);
return () => clearTimeout(timeout);
}, []);
You received this warning because setTimeout
was still on process even of the component was unmounted.您收到此警告是因为即使组件已卸载,
setTimeout
仍在处理中。
The syntax is very easy:语法非常简单:
useEffect(() => {
setTimeout(() => {
setIsLoading(false);
}, 1000);
return () => someCleanUp() // your cleanup function
}, []);
To prevent component not updating state when un-mounted you can use useRef
and cleanup function为了防止组件在卸载时不更新 state,您可以使用
useRef
和清理 function
const mounted = useRef(false);
useEffect(() => {
mounted.current = true;
setTimeout(() => {
if (mounted.current) {
setIsLoading(false);
}
}, 1000);
return function cleanup() {
mounted.current = false;
}
}, []);
Solution解决方案
Using Axios:使用 Axios:
import axios from 'axios';
Component:零件:
const Home: React.FC = () => {
let cancelToken: any = axios.CancelToken;
let source = cancelToken.source();
useEffect(() => {
(async () => {
try {
const data = await axios.get("https://<you-api-url>", {
cancelToken: source.token
});
}catch (error) {
if (axios.isCancel(error)) {
console.log('Request canceled', error.message);
} else {
// handle error
console.log(error);
}
}
})();
return () => {
//when the component unmounts
console.log("component unmounted");
// cancel the request (the message parameter is optional)
source.cancel('Operation canceled by the user.');
}
}, []); //End UseEffect
return ();
};
export default Home;
Above implementation is per the original Axios docs, read here to understand in detail.上面的实现是根据原始的 Axios 文档,阅读这里详细了解。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.