UniversalDataTool / react-image-annotate

Create image annotations. Classify, tag images with polygons, bounding boxes or points.
MIT License
406 stars 177 forks source link

Error when changing between images #163

Closed josepdecid closed 3 years ago

josepdecid commented 3 years ago

When using the prev and next buttons to change between images, the index remains the first. It changes for a moment to Image 2 but it goes back to the first one without showing any error. I'm trying to render it inside the main App component.

I'm using Node v12.18.0 on Windows with the following library versions:

class App extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <ReactImageAnnotate
                labelImages
                regionClsList={["Alpha", "Beta", "Charlie", "Delta"]}
                regionTagList={["tag1", "tag2", "tag3"]}
                images={[
                    {
                        src: "https://placekitten.com/408/287",
                        name: "Image 1",
                        regions: []
                    },
                    {
                        src: "https://placekitten.com/408/287",
                        name: "Image 2",
                        regions: []
                    },
                    {
                        src: "https://placekitten.com/408/285",
                        name: "Image 3",
                        regions: []
                    }
                ]}
            />
        );
    }
}

I attach here a GIF showing the problem: Image

You can see that there are no errors but sometimes the following warning is raised:

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 a useEffect cleanup function. in ImageCanvas (created by MainLayout)

I'm wondering what can cause the problem or how can I fix it.

vasut02 commented 3 years ago

This bug is caused due to state.images in useEffect dependency array


// inside Annotator/index.js  line:165

useEffect(() => {
    if (selectedImage === undefined) return
    console.log('Inside Select Image useEffect');
    dispatchToReducer({
      type: "SELECT_IMAGE",
      imageIndex: selectedImage,
      image: state.images[selectedImage],
    })
  }, [selectedImage , state.images])

so what we can do?

use selectedImage prop and write your own custom Next and Prev function like this


  const [images, setImages] = useState( /** your images (array) will comes come here */ )
  const [selectedImage, setSelectedImage] = useState(0)

  const handleNext = ()=>{
    if ( selectedImage === images.length-1)
      return 
    setSelectedImage(selectedImage + 1)
  }
  const handlePrev = ()=>{
    if (selectedImage === 0) 
      return 
    setSelectedImage(selectedImage - 1)    
  }

  . . . .
  <ReactImageAnnotate
                selectedImage={selectedImage}
                onNextImage={handleNext}
                onPrevImage={handlePrev}
                images={images}   
                . . . . 
josepdecid commented 3 years ago

Great, this works now, but there should be a way to have this already working without overwriting the handlers, as the functionality is a pretty common and straightforward one.