簡體   English   中英

設置 usestate 后如何運行函數並使用 state 值

[英]how to run functions after usestate is set and use the state value

我有一個運行 2 個異步函數的 function。 第一個需要設置 useState 數據,以便第二個可以使用該數據。 然后我試圖獲取該變量並將其傳遞給第三個 function。 為了傳遞 state 變量,我使用了 npm use-between ,它的工作方式類似於 useState。 但是,我無法獲取和傳遞變量。

之間.js -

import { useState, useCallback } from 'react'
import { useBetween } from 'use-between';

const useValues = () => { 
    
    const [hash, setHash] = useState(false);
    const [finalHash, setFinalHash] = useState(false);
    const sH = useCallback(() => setHash(), []);
    const sFH = useCallback(() => setFinalHash(), []);
  
    return {
      hash,
      finalHash,
      sH,
      sFH
    };
  };
  
  export const useSharedValues = () => useBetween(useValues);

創建.js -

    import { useState, useCallback } from 'react';
    import { useSharedValues } from './utils/between';
    import FormData from 'form-data';
    import axios from 'axios';
    
    function useCreate() {  
    const {
    hash,
    finalHash,
    sH,
    sFH } = useSharedValues();
           
        async function create1() {
 myCanvas.toBlob(async function(blob) { // extra function I run to get an image then upload file
                await axios({
                     method: "post",
                     url: "url",
                 }).then((response) => {
                   sH(response.data.Hash); // trying to set state here
                 });
})
        }
       
    async function create2() {      
        var objects = [
               {
                   "hash": hash, // trying to use state in next function
               }
        ]
       
       var data = JSON.stringify(objects)
          
       await axios({
           method: "post",
           url: "url",
           data: data,
       }).then((response) => {
       sFH(response.data.IpfsHash); // set final hash to use in 3rd function
       })
       }
       
    const create = useCallback(async () => {
        await create1(); 
        await create2(); // run after create1 has finished
        console.log(finalHash);
    }, [create1, create2]);
       
    return {create};   
}

在不同文件的另一個組件中調用它 -

import useCreate from "../create.js";

const {create} = useCreate();

    const onPressed = async () => {
    await create();
    await The3rdFunction(); // 3rd function needs to wait for final hash variable so it can use it
    };

現在函數返回未定義。 據我了解,這是因為 useState 是如何工作的,直到下一次渲染它才會顯示該值。 所以我不確定如何實現我的目標?

根據@ilketorun 建議的代碼,我修改了我的代碼並添加了更多內容以進一步說明 -

之間.js

....
const sH = useCallback((event) => setHash(event.target.value), []);
...

創建.js

 function useCreate() {
        const {
            aSharedValue,
          } = useSharedValues();
    
    async function create1() {
        ....
        canvas.toBlob(async function(blob) { // here I upload a file which gives me the hash when done
            const formData = new FormData();
            formData.append('file', blob);
          
              return axios({
              method: "post",
              url: "url",
              data: formData,
              headers: { ... },
          }).then(res => res.data.Hash);
          
          });
    
    }
    
    async function create2(hash) { 
        var objects = [
            {
                "hash": hash,
                "value": aSharedValue
            }
        ]
    
    var data = JSON.stringify(objects)
    
    return axios({
        method: "post",
        url: "url",
        data: data,
        headers: { .... },
    }).then(res => res.data.Hash)
    }
    
    async function create3() {
      const hash = await create1()
      const finalHash = await create2(hash)
      return {hash, finalHash}
    }
    
    return { create1, create2, create3 }
    }
    
    export default useCreate;

然后我嘗試在另一個組件中運行它 -

const onPressed = async () => {  
const finalHash = await create3()
const { success } = NextFunction(finalHash);
}

hash 返回未定義,我無法在 NextFunction 中獲取NextFunction

您可以利用useStateuseEffect掛鈎。 useEffect 將根據其依賴項重新渲染。 例如:

const [myFirstState,setMyFirstState] = useState()
const [mySecondState,setMySecondState] = useState()

useEffect(()=> {
  const myAsyncFunc = async () => {
    // await something here
    let awaitedResult = await someFunction();
    setMyFirstState(awaitedResult)
  }
  myAsyncFunc();
},[])

useEffect(()=> {
  // do stuff with myFirstState
  const myOtherAsyncFunc = async () => {
    // await something here
    let awaitedOtherResult = await someOtherFunction();
    setMySecondState(awaitedOtherResult)
  }
  myOtherAsyncFunc();
},[myFirstState])

useEffect(()=> {
  // do stuff with mySecondState
},[mySecondState])

解耦關注點

創建一個處理您的 get/post 請求並返回適當響應的myapi模塊。 協調多個請求和設置 state 應該是一個單獨的問題 -

// myapi.js
import axios from "axios"

function create1() {
  return axios.post("url").then(res => res.data.Hash)
}

function create2(hash) {
  return axios.post("url", {hash}).then(res => res.data.IpfsHash)
}

async function create3() {
  const hash = await create1()
  const finalHash = await create2(hash)
  return {hash, finalHash}
}

export { create1, create2, create3 }

這約 15 行代碼有效地替換了整個約 50 行create.js文件。

現在在您的組件內 -

import * as myapi from "./myapi"

function MyComponent(...) {
  // ...

  useEffect(_ => {
    myapi.create3()
      .then(({hash, finalHash}) => {
        setHash(hash)
        setFinalHash(finalHash)
      })
      .catch(console.error)
  }, [])
}

useValues 顯示不正確

在您的useValues掛鈎中,您將setHashsetFinalHash包裝在useCallback -

  1. useState返回的set* function 已經是一個“回調”。 沒有必要記住它。
  2. 您創建的函數不會將 arguments 傳遞給set*函數。 沒有 arguments 的setHash()setFinalHash()可以明顯看出這一點。
const useValues = () => { 
  const [hash, setHash] = useState(false)
  const [finalHash, setFinalHash] = useState(false)
  const sH = useCallback(() => setHash(), [])       // <-
  const sFH = useCallback(() => setFinalHash(), []) // <-
  return {
    hash,
    finalHash,
    sH,
    sFH
  }
}

應改為——

const useValues = () => {
  const [hash, setHash] = useState(false)
  const [finalHash, setFinalHash] = useState(false)
  return {
    hash,
    finalHash,
    sH: setHash,       // <--
    sFH: setFinalHash  // <--
  }

這引出了一個問題,你甚至需要這個嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM