Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

93
Vistas
Maximum update depth Exceeded during React Easy Crop

I am trying to get the react-easy-crop library working following this guy's tutorial: https://www.youtube.com/watch?v=RmiP1AY5HFM

However, around the middle of his video, he is able to show his image after selecting the file. In my code, I can see the image for 0.5 seconds, and it disappears because React Crashes with the log: "Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops."

I know there's an infinite loop somewhere but I cannot figure out where...I'm quite new to react.. please help!

    const inputRef = React.useRef();
    const triggerFileSelectPopup = () => inputRef.current.click();
    const [image, setImage] = useState(null);
    const [croppedArea, setCroppedArea] = useState(null);
    const [crop, setCrop] = useState({x:0, y:0});
    const [zoom, setZoom] = useState(1)

    const onCropComplete = () => {}

    const onSelectFile = (event) => {
        if (event.target.files && event.target.files.length > 0) {
            const reader = new FileReader()
            reader.readAsDataURL(event.target.files[0])
            reader.addEventListener('load', ()=> {
                console.log(reader.result);
                setImage(reader.result);
            });
        }
    };

    const CropContainer = () => {
        return (
            <div className='CropContainer'>
                <div className='container-cropper'>
                    <Cropper 
                        image={image} 
                        crop={crop} 
                        zoom={zoom} 
                        aspect={1} 
                        onCropChange={setCrop} 
                        onZoomChange={setZoom} 
                        onCropComplete={onCropComplete}
                    />
                    <Slider />
                </div>
                <div className='container-buttons'>
                    <input 
                        type='file' 
                        accept="image/jpg, image/jpeg, image/png" 
                        ref={inputRef} 
                        style={{display:'none'}}
                        onChange={onSelectFile} 
                    />

                    <Button 
                        variant='contained' 
                        onClick={triggerFileSelectPopup}>Choose New Image
                    </Button>

                    <Button 
                        variant='contained'>Save
                    </Button>
                </div>
            </div>

        );
    }
 
    return (
       <div className="NewDiv">
           <CropContainer />  
       </div>
    );
about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

It seems likely that something the nested CropContainer component does causes the outer component to rerender. When the outer component rerenders, it declares a new CropContainer component, which unmounts the previous "instance" and mounts a new one. This is why it is considered anti-pattern to define React components within other react components.

You can either move the JSX that CropContainer returns, as you've done

return (
  <div className="NewDiv">
    <div className="CropContainer">
      <div className="container-cropper">
        <Cropper
          image={image}
          crop={crop}
          zoom={zoom}
          aspect={1}
          onCropChange={setCrop}
          onZoomChange={setZoom}
          onCropComplete={onCropComplete}
        />
        <Slider />
      </div>
      <div className="container-buttons">
        <input
          type="file"
          accept="image/jpg, image/jpeg, image/png"
          ref={inputRef}
          style={{ display: "none" }}
          onChange={onSelectFile}
        />

        <Button variant="contained" onClick={triggerFileSelectPopup}>
          Choose New Image
        </Button>

        <Button variant="contained">Save</Button>
      </div>
    </div>  
  </div>
);

or you can move the CropContainer declaration outside the outer component. Pass all the callbacks and such in as props.

const CropContainer = ({
  crop,
  image,
  inputRef,
  onCropChange,
  onCropComplete,
  onSelectFile,
  setCrop,
  setZoom,
  triggerFileSelectPopup,
  zoom
}) => {
  return (
    <div className="CropContainer">
      <div className="container-cropper">
        <Cropper
          image={image}
          crop={crop}
          zoom={zoom}
          aspect={1}
          onCropChange={setCrop}
          onZoomChange={setZoom}
          onCropComplete={onCropComplete}
        />
        <Slider />
      </div>
      <div className="container-buttons">
        <input
          type="file"
          accept="image/jpg, image/jpeg, image/png"
          ref={inputRef}
          style={{ display: "none" }}
          onChange={onSelectFile}
        />

        <Button variant="contained" onClick={triggerFileSelectPopup}>
          Choose New Image
        </Button>

        <Button variant="contained">Save</Button>
      </div>
    </div>
  );
};

...

return (
  <div className="NewDiv">
    <CropContainer /* pass all those props here */ />  
  </div>
);
about 4 years ago · Juan Pablo Isaza Denunciar

0

i had this problem myself, when i was opening the modal to crop the image i was getting infinite console.log from onCropComplete, because i was using an image saved in redux state i had to put the image inside a normal state first then put the image into Cropper

const IMG = useSelector((state: RootStateOrAny) => state.create.photoRaw)

const [image, setImage] = useState(URL.createObjectURL(IMG))
const [crop, setCrop] = useState<Point>({ x: 0, y: 0 });
const [zoom, setZoom] = useState(1);

const onCropComplete = useCallback(
    (croppedArea: Area, croppedAreaPixels: Area) => {
        console.log(croppedArea, croppedAreaPixels);
}, []);

<Cropper
     image={image}
     crop={crop}
     zoom={zoom}
     aspect={1 / 1}
     onCropChange={setCrop}
     onCropComplete={onCropComplete}
     onZoomChange={setZoom} />
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda