我有一个叫做ImageDisplay的组件。该组件使用自定义的react钩子(useImageUpload)使用react将图像上传到cloudinary。
自定义钩子useImageUpload包含一个状态,它将上传图像的urls存储在数组中。自定义钩子返回一个对象,该对象包含图像urls数组、用于上载新图像的函数和isLoading布尔值。
正在成功上传图像。但是看起来,这个响应查询片段正在导致内存泄漏。
onSuccess: ({ data }) => {
console.log("Image uploaded successfully");
setImages([...images, data.secure_url]);
},

如何更新onSuccess事件上的图像数组?
ImageDisplay.js
import React, { useEffect } from "react";
import "styles/ImageDisplay.scss";
import { Field } from "formik";
import Skeleton from "react-loading-skeleton";
import "react-loading-skeleton/dist/skeleton.css";
import useImageUpload from "utils/useImageUpload";
export default function ImageDisplay() {
let { images, uploadImage, uploading } = useImageUpload();
const handleFileChange = (e) => {
const inputFile = e.target.files[0];
uploadImage(inputFile);
};
useEffect(() => {
console.log(images);
}, [images]);
return (
<>
<div className="image-display border mb-3 px-3">
<div className="image-preview text-center">
<h6>Upload product images to attract customers</h6>
{/* <Skeleton width={300} height={300} /> */}
</div>
<hr />
<div className="img-choose border p-2 ">
<div className="options">
<Skeleton width={100} height={100} />
<Skeleton width={100} height={100} />
<Skeleton width={100} height={100} />
<Skeleton width={100} height={100} />
<Skeleton width={100} height={100} />
<Skeleton width={100} height={100} />
</div>
</div>
.
</div>
<div className="img-input">
<Field
type="file"
name="productImages"
id="productImages"
onChange={handleFileChange}
accept="image/*"
/>
<h5>Select product images to upload</h5>
</div>
</>
);
}useImageUpload.js
import axios from "axios";
import { useState } from "react";
import { useMutation } from "react-query";
const useImageUpload = () => {
const [images, setImages] = useState([]);
let { isLoading: uploading, mutateAsync: uploadImage } = useMutation(
async (data) => {
let formData = new FormData();
formData.append("file", data);
formData.append("upload_preset", "uploadPresetHere");
formData.append("cloud_name", "nameHere");
return await axios.post(
"cloudinary_url",
formData,
{
withCredentials: false,
}
);
},
{
onSuccess: ({ data }) => {
console.log("Image uploaded successfully");
setImages([...images, data.secure_url]);
},
onError: (error) => {
console.log(error.response);
},
}
);
return { images, uploadImage, uploading };
};
export default useImageUpload;如果我在这个问题上犯了什么错误,很抱歉。
发布于 2022-02-27 10:25:33
这是React查询的一种正常行为:如果使用useMutation卸载执行突变的组件卸载,则仍会调用onSuccess回调。
要修复它,您可以有几个选项:在ref中跟踪组件的挂载/卸载状态:
const mounted = useRef(true)
useEffect(() => {
mounted.current = true
() => mounted.current = false
})
let { ... } = useMutation(
async (data) => {...},
{
onSuccess: ({ data }) => {
if (mounted.current) {
setImages([...images, data.secure_url]);
}
}
}
);但不确定它在所有情况下都能工作,通常在卸载组件时响应删除引用。
另一种解决方案是将图像存储在React查询缓存中。毕竟,它是来自服务器的数据,因此它处于服务器状态,应该驻留在缓存中:
let { ... } = useMutation(
async (data) => {...},
{
onSuccess: ({ data }) => {
queryClient.setQueryData('images', prev => [...prev, data])
}
}
);https://stackoverflow.com/questions/71283217
复制相似问题