react-native-expo-image-cache icon indicating copy to clipboard operation
react-native-expo-image-cache copied to clipboard

componentWillUnmount and Ability to cancel image download

Open wcandillon opened this issue 6 years ago • 9 comments

When navigating through large list of images, there should be an ability to cancel the image caching when unmounting the component

wcandillon avatar Apr 03 '18 09:04 wcandillon

+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 avatar Apr 26 '18 06:04 ZackLeonardo

@ZackLeonardo Have you been experiencing it with 3.0.2? This should have been fixed now.

wcandillon avatar Apr 26 '18 06:04 wcandillon

@wcandillon thanks, just try it.

ZackLeonardo avatar Apr 26 '18 08:04 ZackLeonardo

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.

jamland avatar May 02 '18 08:05 jamland

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 .

wcandillon avatar May 02 '18 09:05 wcandillon

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 avatar May 02 '18 12:05 wcandillon

@wcandillon thank you for so quick update! so far 3.0.3 works well for me for those cases I had

jamland avatar May 03 '18 10:05 jamland

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);

hernanif1 avatar Oct 01 '18 08:10 hernanif1

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

lawrence-laz avatar Dec 07 '21 19:12 lawrence-laz