advanced-cropper / react-advanced-cropper

The react cropper library that embraces power of the advanced cropper core to give the possibility to create croppers that exactly suited for your website design
https://advanced-cropper.github.io/react-advanced-cropper/
Other
692 stars 34 forks source link

FixedCropper crashes if loaded in a hidden tab #70

Open robinandeer opened 3 months ago

robinandeer commented 3 months ago

Hey! This is such a sweet library that fits our use case really well :D

However, we are noticing an annoying crash when we render the cropper in a background/hidden tab.

The flow is as follows:

  1. user uploads an image
  2. use switches to a different tab
  3. upload completes and we load the cropper component
  4. user switches back to the tab
  5. the cropper has crashed with the following stack trace
TypeError: Cannot read properties of null (reading 'width')
    at getStencilSize (index.esm-bundler.js:4692:14)
    at Object.aspectRatio (index.esm-bundler.js:4743:23)
    at Object.aspectRatio (index.esm-bundler.js:2324:78)
    at getAspectRatio (index.esm-bundler.js:842:74)
    at setCoordinates (index.esm-bundler.js:1076:23)
    at createState (index.esm-bundler.js:1211:17)
    at AbstractCropperInstance.createDefaultState (index.esm-bundler.js:2765:53)
    at AbstractCropperInstance.resetState (index.esm-bundler.js:2452:37)
    at AbstractCropperInstance.reset (index.esm-bundler.js:2567:19)
    at eval (index.esm-bundler.js:3637:37)
The above error occurred in the <ForwardRef(AbstractCropperComponent)> component:

    at AbstractCropperComponent (webpack-internal:///./node_modules/react-advanced-cropper/dist/index.esm-bundler.js:4620:23)
    at eval (webpack-internal:///./node_modules/react-advanced-cropper/dist/index.esm-bundler.js:4777:24)

We are running the following setup:

├── react-advanced-cropper@0.20.0
├── react-dom@17.0.2
├── react@17.0.2
├── styled-components@5.1.1

Let me know if I can help you replicate the issue!

I've implemented a fix that only renders the cropper if the tab is active but this feels like logic that belongs in the library if it is really needed:

// React Advanced Cropper crashes if loaded in a hidden tab
const [isTabActive, setIsTabActive] = useState(!document.hidden);
useEffect(() => {
  function updateVisibility() {
    setIsTabActive(!document.hidden);
  }

  document.addEventListener('visibilitychange', updateVisibility);
  return () => {
    document.removeEventListener('visibilitychange', updateVisibility);
  };
}, []);

cc @bryanlohjy

Norserium commented 3 months ago

@robinandeer, hello!

Could you create the sandbox to reproduce this issue? It looks pretty strange at the first glance.