Javascript React自定义钩子使返回函数在事件上可执行

Javascript React自定义钩子使返回函数在事件上可执行,javascript,reactjs,typescript,react-hooks,Javascript,Reactjs,Typescript,React Hooks,我已经创建了一个用于处理上传到AWS s3 bucket的定制钩子,但我面临一个小问题。我不希望我的钩子直接执行逻辑,所以我创建了一个可执行函数,然后返回。唯一的问题是没有从handleUpload函数内部设置状态 以下是我试图做的: import React, { useState } from "react"; const useS3Aws = () => { const [isLoading, setIsLoading] = useState(false);

我已经创建了一个用于处理上传到AWS s3 bucket的定制钩子,但我面临一个小问题。我不希望我的钩子直接执行逻辑,所以我创建了一个可执行函数,然后返回。唯一的问题是没有从
handleUpload
函数内部设置状态

以下是我试图做的:

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;
import React,{useState}来自“React”;
常量useS3Aws=()=>{
const[isLoading,setIsLoading]=useState(false);
const[uploadedrl,setuploadedrl]=useState(“”);
const handleUpload=async(文件:any,s3FolderPath:string)=>{
setIsLoading(true);//问题就在这里(状态未更新)
//使用AWS s3处理上传
//代码。。。。。。
//使用从s3返回的实时url设置状态
setUploadedUrl(“实时url”);//问题就在这里(状态未更新)
console.log(uploadedrl);//它打印一个空字符串
setIsLoading(true);//问题就在这里(状态未更新)
};
返回[
孤岛,
上传,
(文件:any,s3FolderPath:string)=>handleUpload(文件,s3FolderPath),
]作为常量;
};
常量上传歌曲=()=>{
const[isLoading,UploadeUrl,handleUpload]=useS3Aws();
const handleSong=async()=>{
常量文件={
//对象数据
};
handleUpload(文件,“音乐”);
console.log(uploadedrl);//为空
};
返回(
实时URL:{uploadedUrl?uploadedUrl:“无链接”}

handleSong()}> 点击我 ); } 导出默认上传歌曲;

您的钩子看起来不错,但您没有正确使用它的返回值

<button onClick={() => handleSong}>
或者,如果不想传递参数,可以:

<button onClick={handleSong}>

当您设置状态时,它是异步的。状态设置正确,但任何局部变量都将反映以前的状态,因为重新渲染尚未发生。通常这一点都不重要,因为当您单击“工作”按钮时,UI会立即更新。

是不是您在每个上下文中将SetIsUpload设置为true的问题?我认为问题在于AWS钩子的使用,因为当我调用
setUploadedUrl
setIsLoading
时,它不会更新它。您也可以控制台记录它。它不会更新,因为您没有调用状态更新发生的
handleSong
。在钩子的
handleSong
顶部添加一个
console.log(“调用的handleSong”)
,以验证是否调用了该函数。调用该函数是因为我可以在将链接设置为状态之前对链接进行控制台日志记录。我重新创建了钩子,以模拟这种情况,您也可以这样尝试
handleSong()}>
我复制并粘贴了钩子,我所做的唯一更改是添加了正确调用
handleChange
的按钮,它完全按照您的预期操作。所以,如果你看到了一些不同的东西,那就是你还没有发布的代码中的一个bug。请参阅我的编辑,它解释了一些可能会绊倒你的东西。
<button onClick={handleSong}>
console.log(uploadedUrl); // it is empty