Search code examples
javascriptreactjsreact-hookscropperjs

Cannot read property 'getData' of null, when keep aspectratio in state


i try to set minimum data dimentions in cropper, it works only when aspect-ratio is hardcoded, but if i keep aspect-ratio in state, cropper throw an error:

Cannot read property 'getData' of null.

How to fix it? I'll be thankfull for every advice. Here is my code simple:

import React, {
  useState,
  useRef,
  useCallback
} from "react";
import ReactDOM from "react-dom";
import Cropper from "react-cropper";
import "cropperjs/dist/cropper.css";

const Demo = props => {
  let cropper = useRef(null);
  const [aspectWidth, setaspectWidth] = useState(1);
  const [aspectHeight, setaspectHeigh] = useState(1);

  const setHeight = useCallback(event => {
    setaspectHeigh(parseInt(event.currentTarget.value));
  }, []);

  const setWidth = useCallback(event => {
    setaspectWidth(parseInt(event.currentTarget.value));
  }, []);

  const showData = useCallback(() => {
    const data = cropper.getData();
    if (data.width < 100) {
      data.width = 100;
      cropper.setData(data);
    }
    if (data.height < 100) {
      data.height = 100;
      cropper.setData(data);
    }
  }, []);
  return (
    <div>
      <Cropper
        autoCrop={true}
        cropmove={showData}
        scalable={true}
        src="https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg? 
        auto=compress&cs=tinysrgb&dpr=1&w=500"
        style={{ width: "520px", height: "520px" }}
        aspectRatio={aspectWidth / aspectHeight}
        ref={el => {
          cropper = el;
        }}
        autoCropArea={1}
        viewMode={3}
      />
      <div className="crop-right-size">
        <div className="crop-right-width">
          <p>Width</p>
          <input type="text" onChange={setWidth} value={aspectWidth} />
        </div>
        <div className="crop-right-height">
          <p>Height</p>
          <input type="text" onChange={setHeight} value={aspectHeight} />
        </div>
      </div>
    </div>
  );
};
export default Demo;

Solution

  • try this:

    import React, {
    
    
    useState,
      useRef,
      useCallback
    } from "react";
    import ReactDOM from "react-dom";
    import Cropper from "react-cropper";
    import "cropperjs/dist/cropper.css";
    
    const Demo = props => {
      let cropper = useRef(null);
      const [aspectWidth, setaspectWidth] = useState(1);
      const [aspectHeight, setaspectHeigh] = useState(1);
    
      const setHeight = useCallback(event => {
        setaspectHeigh(parseInt(event.currentTarget.value));
      }, []);
    
      const setWidth = useCallback(event => {
        setaspectWidth(parseInt(event.currentTarget.value));
      }, []);
    
      const showData = useCallback(() => {
        const data = cropper.current.getData();
        if (data.width < 100) {
          data.width = 100;
          cropper.setData(data);
        }
        if (data.height < 100) {
          data.height = 100;
          cropper.current.setData(data);
        }
      }, []);
      return (
        <div>
          <Cropper
            autoCrop={true}
            cropmove={showData}
            scalable={true}
            src="https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg? 
            auto=compress&cs=tinysrgb&dpr=1&w=500"
            style={{ width: "520px", height: "520px" }}
            aspectRatio={aspectWidth / aspectHeight}
            ref={cropper}
            autoCropArea={1}
            viewMode={3}
          />
          <div className="crop-right-size">
            <div className="crop-right-width">
              <p>Width</p>
              <input type="text" onChange={setWidth} value={aspectWidth} />
            </div>
            <div className="crop-right-height">
              <p>Height</p>
              <input type="text" onChange={setHeight} value={aspectHeight} />
            </div>
          </div>
        </div>
      );
    };
    export default Demo;