Parent not updating child state - React & ImageCrop

Viewed 26

I am having some issues with a cropping tool I am building where the child (CropImage component) has not received the updated state of the image that is set through the ImageForm component.

All variables are parts of the props passed from the parent component (App), as I will need to pass them along the children.

The issue: When running the getCroppedImage function, the props.image.target is undefined however in the console log just above it, it is logging the element just fine.

The CropImage component should not be able to load if the image is not set, but it is still received as undefined.

Am I missing something here? Tried looking into useEffect, but given that the getCroppedFunction (i.e. renderFunction) runs when the cropping is complete I cannot run the function through useEffect.

I have shortened the code for simplicity, but the structure is as the below:

function ImageForm(props) {
  //Update the image
  const handleImage = async (event) => {
    props.setImgSrc(URL.createObjectURL(event.target.files[0]));
  };

  return (
    <Row>
        <Form.Group className="fileSelector my-3">
          <Form.Control type="file" onChange={handleImage}></Form.Control>
        </Form.Group>
         //Setting the image
        {props.image && <img src={props.imgSrc} onLoad={props.setImage} alt="" />}
    </Row>
  );
}

export default ImageForm;

function App() {
          const [finalCrops, setFinalCrops] = useState([]);
          const [fileFormats, setFileFormats] = useState(['320x320']);
          const [imgSrc, setImgSrc] = useState([]);
          const [image, setImage] = useState([]);
        
          const setImageFunc = (img) => {
            return setImage(prev => img);
          }
        
          return (
            <div className="App" fluid="md">
              <div className="sectionOne">
                <Form className="sidebar">
                  <ImageForm
                    imgSrc={imgSrc}
                    setImgSrc={setImgSrc}
                    setImage={setImageFunc}
                    image={image}
                  ></ImageForm>
              </div>
              <div className="sectionTwo">
              {image.target && fileFormats.map((val) => {
                return (
                  <CropImage
                    dimensions={val}
                    imgSrc={imgSrc}
                    image={image}
                    key={val}
                  ></CropImage>
                );
              })}
              </div>
            </div>
          );
        }
        
        export default App;````


Crop image component
```jsx 
function CropImage(props) {
      const [crop, setCrop] = useState({ x: 0, y: 0 });
      const [width, setWidth] = useState(null);
      const [height, setHeight] = useState(null);
      const [zoom, setZoom] = useState(1);
      const [result, setResult] = useState(null);
    
      const onCropComplete = useCallback((croppedArea, croppedAreaPixels) => {
          getCroppedImg(croppedArea, croppedAreaPixels);
      }, []);
    
      const getCroppedImg = async (croppedArea, croppedAreaPixels) => {
        try {
          const canvas = document.createElement("canvas");
          canvas.width = width;
          canvas.height = height;
          const ctx = canvas.getContext("2d");
          console.log(props.image.target);
          ctx.drawImage(
            props.image.target, //Undefined at this stage
            croppedAreaPixels.x * zoom,
            croppedAreaPixels.y * zoom,
            croppedAreaPixels.width * zoom, 
            croppedAreaPixels.height * zoom,
            0,
            0,
            width,
            height
          );
          const base64Image = canvas.toDataURL("image/jpeg", 1);
          setResult(base64Image);
        } catch (e) {
          console.log("crop the image \n" + e);
        }
      };
    
    
      useEffect(() => {
        setWidth((width) => parseInt(props.dimensions.split("x")[0]));
        setHeight((height) => parseInt(props.dimensions.split("x")[1]));
      }, [props.dimensions]);
    

    
      return (
        <div className="cropImageContainer mb-5">
            <Row
              className="cropImageInner"
              id={props.dimensions}
            >
              <Col>{width && height && return (
            <Cropper
              image={props.imgSrc}
              crop={crop}
              cropSize={{ width: width, height: height }}
              zoom={zoom}
              onCropChange={setCrop}
              onCropComplete={onCropComplete}
              onZoomChange={setZoom}
            />}
              </Col>
            </Row>
          <div>{result && <img src={result} />}</div>
        </div>
      );
    }
    
    export default CropImage; 



0 Answers
Related