一只名叫tom的猫
这段代码中不需要使用useEffect和useCallback 。ReactCrop 为您提供了 onComplete,因此您唯一需要做的就是在那之后开始绘图。API错误:在上面的代码中,您将 base64 字符串发送到 api,但正如我们在错误 api 中看到的,文件格式除外。还需要将名称设置为 blob才能识别为文件。我收集了这些更改,并且此代码应该可以工作:export default function ProfilePicEdit() { const [upImg, setUpImg] = useState(); const imgRef = useRef(null); const canvasRef = useRef(null); const [crop, setCrop] = useState({ unit: "%", width: 30, aspect: 1 / 1 }); const croppedImage = useRef(null); const onSelectFile = (e) => { if (e.target.files && e.target.files.length > 0) { const reader = new FileReader(); reader.addEventListener("load", () => setUpImg(reader.result)); reader.readAsDataURL(e.target.files[0]); } }; const onLoad = (img) => { imgRef.current = img; }; const onCropComplete = (crop) => { makeClientCrop(crop); }; const makeClientCrop = async (crop) => { if (imgRef.current && crop.width && crop.height) { croppedImage.current = await getCroppedImg( imgRef.current, crop, "newFile.jpeg" ); } }; const getCroppedImg = (image, crop, fileName) => { if (!canvasRef.current || !imgRef.current) { return; } const canvas = canvasRef.current; const scaleX = image.naturalWidth / image.width; const scaleY = image.naturalHeight / image.height; const ctx = canvas.getContext("2d"); canvas.width = crop.width * pixelRatio; canvas.height = crop.height * pixelRatio; ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0); ctx.imageSmoothingQuality = "high"; ctx.drawImage( image, crop.x * scaleX, crop.y * scaleY, crop.width * scaleX, crop.height * scaleY, 0, 0, crop.width, crop.height ); return new Promise((resolve, reject) => { canvas.toBlob((blob) => { if (!blob) { //reject(new Error('Canvas is empty')); console.error("Canvas is empty"); return; } blob.name = fileName; resolve(blob); }, "image/jpeg"); }); }; const onSubmit = (e) => { let formData = new FormData(); formData.append("profile_pic", croppedImage.current, croppedImage.current.name); axiosInstance.put('api/profile/update/', formData) window.location.reload(); }; return ( <div className="imagecropper"> <form className={classes.form} noValidate onSubmit={handleSubmit(onSubmit)}> <div> <label htmlFor="profile-pic"> <input accept="image/*" id="profile-pic" onChange={onSelectFile} name="image" type="file" /> <div className="profile_pic__edit_main"> <img style={{ width: 40, height: 40 }} src={upImg} className="profile__pic_edit" alt="" /> </div> </label> </div> <ReactCrop src={upImg} onImageLoaded={onLoad} crop={crop} onChange={(c) => setCrop(c)} onComplete={onCropComplete} /> <div> <canvas ref={canvasRef} /> </div> <Button type="submit" fullWidth variant="contained" color="primary" className={classes.submit} > Update </Button> </form> </div> );}