在 api 调用之前反应 useState 钩子更新

React useState hook update before api call

我有一个运行验证并根据检查结果设置状态变量的函数。我需要通过 API 调用传递要上传的变量。

我的问题是当我需要在 api 调用中传递更新后的 serviceSelected 变量时,状态变量没有更新并且传递初始状态 ( null )。

我将如何解决这个问题?

当前代码

const [serviceSelected, setServiceSelected] = useState(null)

function checkServicesSelected () {

       if (photography === true && video === false && drone === false){
            setServiceSelected(PhotographyService);
        } else if(photography === true && video === true && drone === false){
            setServiceSelected(PhotographyVideoService);
        } else if (photography === true && video === true && drone === true){
            setServiceSelected(allThreeServices);
        } else if (photography === false && video === true && drone === false){
            setServiceSelected(VideoService);
        } else if (photography === false && video === true && drone === true){
            setServiceSelected(VideoDroneService);
        } else if (photography === true && video === false && drone === true){
            setServiceSelected(PhotographyDroneService);
        } else if (photography === false && video === false && drone === true){
            setServiceSelected(DroneService);
        }
    }


/// first runs the check, then makes an api call. 

 async function completeApplication() {

    setShowSubmitForm(true);        

    try {
        /// run check
        await checkServicesSelected()

        /// pass info to uploadInfo Function 
        const UploadProspectInfo = await UploadInfo({service: serviceSelected})

     } catch (e) {
       alert(e.message);

          }

       setShowThankYou(true); 
   }

更新后的代码现在可以工作了

 useEffect(() => {
    if(serviceSelected){
        UploadInfo({service: serviceSelected})
        .catch(function (e) {
            alert(e.message);
        });
        setShowThankYou(true)
    }
}, [serviceSelected]);


function completeApplication() {
        setShowSubmitForm(true);
        checkServicesSelected();  
    }

可以使用useEffect hook来实现

...
...
React.useEffect(() => {
(async function() {
  try {
         /// pass info to uploadInfo Function 
         const UploadProspectInfo = serviceSelected && await UploadInfo({service: serviceSelected})
         //serviceSelected && setShowThankYou(true); // you need it here?

    }catch (e) {
       alert(e.message);
     }
})();

  }, [serviceSelected]);


/// first runs the check, then makes an api call. 

function completeApplication() {

        setShowSubmitForm(true);        

        /// run check
        checkServicesSelected()

        //setShowThankYou(true); // maybe you don't need it here?
   }

旁注:

01) self-invoking function

02) async in useEffect

setServiceSelected 重新渲染组件,所以这一行将有旧的 serviceSelected 值:

const UploadProspectInfo = await UploadInfo({service: serviceSelected})

因此,如果您想在状态中存储 serviceSelected 值(除了进行 api 调用以外的其他目的),您有两种选择,您必须像这样使用 useEffect:

 useEffect(() => {
    if(serviceSelected){
        UploadInfo({ service: serviceSelected })
        .catch(function (e) {
            alert(e.message);
        });
    }
}, [serviceSelected]);


/// first runs the check, then makes an api call. 

function completeApplication() {
    setShowSubmitForm(true);
    checkServicesSelected();
    setShowThankYou(true);
}

但如果您不想存储在状态中,您可以将 checkServicesSelected 函数设为纯函数,return 选定的服务而不是存储在状态中。