繁体   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