本文介绍了在 React 功能组件中使用 async/await的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我刚刚开始在一个项目中使用 React,我真的很努力将 async/await 功能合并到我的一个组件中.

I'm just beginning to use React for a project, and am really struggling with incorporating async/await functionality into one of my components.

我有一个名为 fetchKey 的异步函数,它可以从我通过 AWS API Gateway 提供的 API 获取访问密钥:

I have an asynchronous function called fetchKey that goes and gets an access key from an API I am serving via AWS API Gateway:

const fetchKey = async authProps => {
  try {
    const headers = {
      Authorization: authProps.idToken // using Cognito authorizer
    };

    const response = await axios.post(
      "https://MY_ENDPOINT.execute-api.us-east-1.amazonaws.com/v1/",
      API_GATEWAY_POST_PAYLOAD_TEMPLATE,
      {
        headers: headers
      }
    );
      return response.data.access_token;

  } catch (e) {
    console.log(`Axios request failed! : ${e}`);
    return e;
  }
};

我正在使用 React 的 Material UI 主题,并且不想使用它的仪表板模板之一.不幸的是,仪表板模板使用了一个功能性无状态组件:

I am using React's Material UI theme, and waned to make use of one of its Dashboard templates. Unfortunately, the Dashboard template uses a functional stateless component:

const Dashboard = props => {
  const classes = useStyles();

  const token = fetchKey(props.auth);
  console.log(token);

  return (
  ... rest of the functional component's code

我的console.log(token) 的结果是一个 Promise,这是意料之中的,但是我的 Google Chrome 浏览器中的屏幕截图有些矛盾 - 它是待定的,还是已解决?

The result of my console.log(token) is a Promise, which is expected, but the screenshot in my Google Chrome browser is somewhat contradictory - is it pending, or is it resolved?

第二,如果我尝试 token.then((data, error)=> console.log(data, error)),我得到 undefined变量.这对我来说似乎表明该函数尚未完成,因此尚未解析 dataerror 的任何值.然而,如果我尝试放置一个

Second, if I try instead token.then((data, error)=> console.log(data, error)), I get undefined for both variables. This seems to indicate to me that the function has not yet completed, and therefore has not resolved any values for data or error. Yet, if I try to place a

const Dashboard = async props => {
  const classes = useStyles();

  const token = await fetchKey(props.auth);

React 强烈抱怨:

React complains mightily:

> react-dom.development.js:57 Uncaught Invariant Violation: Objects are
> not valid as a React child (found: [object Promise]). If you meant to
> render a collection of children, use an array instead.
>     in Dashboard (at App.js:89)
>     in Route (at App.js:86)
>     in Switch (at App.js:80)
>     in div (at App.js:78)
>     in Router (created by BrowserRouter)
>     in BrowserRouter (at App.js:77)
>     in div (at App.js:76)
>     in ThemeProvider (at App.js:75)

现在,我将首先声明我没有足够的经验来了解此错误消息的原因.如果这是一个传统的 React 类组件,我会使用 this.setState 方法来设置一些状态,然后继续我的快乐之路.但是,我在此功能组件中没有该选项.

Now, I'll be the first to state I don't have enough experience to understand what is going on with this error message. If this was a traditional React class component, I'd use the this.setState method to set some state, and then go on my merry way. However, I don't have that option in this functional component.

如何将 async/await 逻辑合并到我的功能性 React 组件中?

How do I incorporate async/await logic into my functional React component?

所以我只想说我是个白痴.返回的实际响应对象不是 response.data.access_token.它是 response.data.Item.access_token.呸!这就是为什么结果被返回为 undefined,即使实际的 promise 已经解决.

So I will just say I'm an idiot. The actual response object that is returned is not response.data.access_token. It was response.data.Item.access_token. Doh! That's why the result was being returned as undefined, even though the actual promise was resolved.

推荐答案

你必须确定两件事

  • useEffect 类似于componentDidMountcomponentDidUpdate,所以如果你在这里使用setState 那么你需要限制用作 componentDidUpdate 时的代码执行如下所示:
  • useEffect is similar to componentDidMount and componentDidUpdate, so if you use setState here then you need to restrict the code execution at some point when used as componentDidUpdate as shown below:
function Dashboard() {
  const [token, setToken] = useState('');

  useEffect(() => {
    // You need to restrict it at some point
    // This is just dummy code and should be replaced by actual
    if (!token) {
        getToken();
    }
  }, []);

  const getToken = async () => {
    const headers = {
      Authorization: authProps.idToken // using Cognito authorizer
    };
    const response = await axios.post(
      "https://MY_ENDPOINT.execute-api.us-east-1.amazonaws.com/v1/",
      API_GATEWAY_POST_PAYLOAD_TEMPLATE,
      { headers }
    );
    const data = await response.json();
    setToken(data.access_token);
  };

  return (
    ... rest of the functional component's code
  );
}

这篇关于在 React 功能组件中使用 async/await的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 12:13