react-native-image-viewing icon indicating copy to clipboard operation
react-native-image-viewing copied to clipboard

Change imageIndex after initialization causes flickering

Open matthewma7 opened this issue 5 years ago • 10 comments

If the imageIndex changed when being visible, the component will flicker. It looks like it's caused by the key change by this line. I am wondering why the key is needed.

matthewma7 avatar May 25 '20 17:05 matthewma7

@matthewma7 Hi! did you find the solution to this yet?

Ace000001 avatar Jun 18 '20 04:06 Ace000001

Same here. Any solution by anyone? @matthewma7 I believe the key is added to fix the issue reported in this thread https://github.com/facebook/react-native/issues/9195#issuecomment-238190537

Try removing it and you'll probably see the image does not update.

altany avatar Jul 02 '20 10:07 altany

@altany only solution i found is not to change the state variable which is being used by imageIndex property. But if you must change the imageIndex while the viewer is visible, unfortunately flicker is there and they haven't fixed it yet.

Ace000001 avatar Jul 02 '20 13:07 Ace000001

for me it forked to randomly assign imageIndex only once when component is mounted and if image is changed, it only takes to refresh screen, may not be the best solution, but at least image is not flickering

const randomValue = useMemo(()=>Math.random(), [])

<Image src={{uri: https://image/image.jpg?id={randomValue}}}/>

Leleka14 avatar Dec 09 '21 10:12 Leleka14

@matthewma7 @Ace000001 @altany have you got any success on this issue ?

VasimSegwitz avatar Jun 27 '22 07:06 VasimSegwitz

After some tests, I verified that by removing the onImageIndexChange prop the flickering stops.

Cnilton avatar Feb 15 '23 19:02 Cnilton

Reading @altany comment, I think imageIndex actually works like inititalImageIndex, meaning it should not be changed.

  1. If your starting image index is startIndex, then pass that imageIndex={startIndex}, but then do not change this startIndex value. Previously i was updating startIndex also on onImageIndexChange={(index)=>setStartIndex(index)} which was causing flickering
  2. Now i am using another variable for onImageIndexChange={(index)=>setCurrentIndex(index)}, and using currentIndex to update header and footers.

AmitDigga avatar Aug 08 '23 07:08 AmitDigga

This solution meets my needs. Just make sure not to use a dynamic imageIndex.

import React from 'react';
import {Text, StyleSheet} from 'react-native';
import ImageView from 'react-native-image-viewing';

/**
 * Props for the PhotoGallery component.
 */
interface Props {
  currentIndex: number;
  images: {uri: string}[];
  onRequestClose: () => void;
  onImageIndexChange: (index: number) => void;
}

export function PhotoGallery(props: Props) {
  const [index] = React.useState(props.currentIndex);

  return (
    <ImageView
      visible
      imageIndex={index}
      images={props.images}
      onRequestClose={props.onRequestClose}
      HeaderComponent={PhotoGalleryHeader}
      onImageIndexChange={props.onImageIndexChange}
    />
  );
}

type PhotoGalleryHeader = React.ComponentProps<typeof ImageView>['HeaderComponent'];

const PhotoGalleryHeader: PhotoGalleryHeader = ({imageIndex}) => (
  <Text style={styles.whiteText}>Image Number - {imageIndex + 1}</Text>
);

const styles = StyleSheet.create({whiteText: {color: 'white', textAlign: 'center', marginTop: 10}});

hrdyjan1 avatar Mar 08 '24 08:03 hrdyjan1