Reputation: 738
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 %s.%s, a useEffect cleanup 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>
);
}
Upvotes: 0
Views: 3477
Reputation: 1796
Solution
Using 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.
Upvotes: 0
Reputation: 768
To prevent component not updating state when un-mounted you can use useRef
and cleanup function
const mounted = useRef(false);
useEffect(() => {
mounted.current = true;
setTimeout(() => {
if (mounted.current) {
setIsLoading(false);
}
}, 1000);
return function cleanup() {
mounted.current = false;
}
}, []);
Upvotes: 0
Reputation: 477
You should always clear setTimeout
s setInterval
s on unmount.
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.
Upvotes: 1
Reputation: 2104
The syntax is very easy:
useEffect(() => {
setTimeout(() => {
setIsLoading(false);
}, 1000);
return () => someCleanUp() // your cleanup function
}, []);
Upvotes: 0