react-native-expo-image-cache
react-native-expo-image-cache copied to clipboard
componentWillUnmount and Ability to cancel image download
When navigating through large list of images, there should be an ability to cancel the image caching when unmounting the component
+1. Warning: Can't call setState (or forceUpdate) 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 the componentWillUnmount method.
@ZackLeonardo Have you been experiencing it with 3.0.2
? This should have been fixed now.
@wcandillon thanks, just try it.
Have related warning with 3.0.2
:
Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op. Please check the code for the Image component.
I can confirm the issue indeed for an edge case 👍🏻. A fix will come asap.
On Wed, May 2, 2018 at 10:10 AM, Andy Burkovetsky [email protected] wrote:
Have related warning with 3.0.2:
Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op. Please check the code for the Image component.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/wcandillon/react-native-expo-image-cache/issues/56#issuecomment-385898350, or mute the thread https://github.com/notifications/unsubscribe-auth/AASr1s7sGxfifJioEjzcWpJKLKFuYVr0ks5tuWoTgaJpZM4TEt2w .
Can you guys try with 3.0.3
. It fixes an edge case. Hopefully this warning should be gone for good now. Feel free to reopen if it's not fixed.
@wcandillon thank you for so quick update!
so far 3.0.3
works well for me for those cases I had
What I'm doing
HOC -> withCache.js
import React, { type ComponentType } from 'react';
import { CacheManager } from 'react-native-expo-image-cache';
type ConfigType = (props: Object) => ?string;
type StateType = {
uri: ?string,
onError: boolean,
};
const withCache = (config: ConfigType) => (
WrappedComponent: ComponentType<*>
) => {
class Cache extends React.Component<{}, StateType> {
isCancelled = false;
state = {
uri: null,
onError: false,
};
async componentDidMount() {
const source = config(this.props);
const uri = await CacheManager.get(source).getPath();
const newState = uri ? { uri } : { onError: true };
if (!this.isCancelled) {
this.setState(newState);
}
}
componentWillUnmount() {
this.isCancelled = true;
}
render() {
return <WrappedComponent {...this.props} {...this.state} />;
}
}
return Cache;
};
export default withCache;
Implementation Images.js
import React from 'react';
import { compose } from 'recompose';
import Container from '../Container/Container';
import { ImageStyled, ImageNotFound } from './ImageStyles';
import withCache from '../../hocs/withCache';
import Loader from '../Loader/Loader';
type PropsType = {
source?: string,
sourceOnError: string,
uri: ?string,
onError: boolean,
};
class Image extends React.Component<PropsType> {
render() {
const { uri, onError, sourceOnError } = this.props;
if (onError) {
return <ImageNotFound resizeMode="contain" source={sourceOnError} />;
}
if (!uri) {
return (
<Container>
<Loader />
</Container>
);
}
return <ImageStyled source={{ uri }} />;
}
}
export default compose(withCache((props: PropsType) => props.source))(Image);
Just got:
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 the componentWillUnmount method.
at node_modules/react/cjs/react.development.js:471:2 in Component.prototype.setState
at node_modules/react-native-expo-cached-image/index.js:64:18 in CachedImage#loadImage
but it doesn't show up very often