I have created a custom hook for handling the uploads to AWS s3 bucket but I am facing a small problem. I did not want my hook to execute the logic directly so I created an executable function that I am then returning. The only problem is that the state is not being set from inside the handleUpload
function
Here is what I am trying to do:
import React, { useState } from "react";
const useS3Aws = () => {
const [isLoading, setIsLoading] = useState(false);
const [uploadedUrl, setUploadedUrl] = useState("");
const handleUpload = async (file: any, s3FolderPath: string) => {
setIsLoading(true); // the problem is here (state not being updated)
// handle the uploading with AWS s3
// code ......
// setting the state with returned live url from s3
setUploadedUrl("the live url"); // the problem is here (state not being updated)
console.log(uploadedUrl); // it prints an empty string
setIsLoading(true); // the problem is here (state not being updated)
};
return [
isLoading,
uploadedUrl,
(file: any, s3FolderPath: string) => handleUpload(file, s3FolderPath),
] as const;
};
const UploadSong = () => {
const [isLoading, uploadedUrl, handleUpload] = useS3Aws();
const handleSong = async () => {
const file = {
// object data
};
handleUpload(file, "music");
console.log(uploadedUrl); // it is empty
};
return (
<div>
<p>Live URL: {uploadedUrl ? uploadedUrl : "No Link"}</p>
<button onClick={() => handleSong()}>
Click me
</button>
</div>
);
}
export default UploadSong;
Your hook looks fine, but you aren't using it's returned values right.
<button onClick={() => handleSong}>
That doesn't actually call handleSong
on click. This calls a function that merely returns the handleSong
function on click.
You want:
<button onClick={() => handleSong()}>
Or if you don't want to pass arguments, you can just:
<button onClick={handleSong}>
One point where you may be confused here:
console.log(uploadedUrl); // it is empty
When you set state, it's asynchronous. State is being set properly, but any local variables will reflect the previous state, because the re-render has not yet happened. Usually this doesn't matter at all, because as you can see here the UI updates immediately when you click the working button.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.