I have a nested component that initiates a HTTP request for uploading an image. It displays progress.
const PreviewItem = React.memo(function PreviewItem(props: PreviewItemProps) {
const {fileObject, handleRemove, classes, onUploadFinished} = props
const [isLoading, setIsLoading] = useState(false)
const [completed, setCompleted] = useState(0);
const cancelTokenSource = axios.CancelToken.source();
useEffect(() => {
const data = new FormData();
data.append('file', fileObject.file);
const config: AxiosRequestConfig = {
onUploadProgress: function (progressEvent) {
const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
setCompleted(percentCompleted)
},
cancelToken: cancelTokenSource.token
};
if (!fileObject.isUploaded) {
setIsLoading(true)
avantiApi.post<DirectUploadResponse>("images/upload", data, config).then(response => {
setIsLoading(false)
if (onUploadFinished) {
onUploadFinished(response.data, fileObject)
}
}).catch(e => console.log("Upload Error", e))
}
return function abortUpload() {
console.log("Use effect...aborting...")
cancelTokenSource.cancel("Cancelled")
}
}, [fileObject])
return <> ..... </>
}, function (prevProps: Readonly<PropsWithChildren<PreviewItemProps>>, nextProps: Readonly<PropsWithChildren<PreviewItemProps>>) {
const areEqual = prevProps.fileObject === nextProps.fileObject
console.log("Are equal?", areEqual)
return areEqual
})
My issue is that even though React.memo’s propsAreEqual function returns true, the component rerenders - if the parent rerenders - while the image is being uploaded, making the request to restart.
Do I miss something on the usage of React.memo?