在React功能组件中使用async/await [英] Using async/await inside a React functional component

查看:2287
本文介绍了在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主题,并希望使用其Dashboard模板之一.不幸的是,仪表板模板使用了功能性的无状态组件:

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-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.

如何将异步/等待逻辑整合到我的功能性React组件中?

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

编辑:所以我只想说我是个白痴.返回的实际响应对象不是response.data.access_token.是response.data.Item.access_token. h!这就是为什么即使实际的诺言已经解决,结果也仍以未定义的形式返回的原因.

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.

推荐答案

您将必须确保两件事

  • useEffectcomponentDidMountcomponentDidUpdate类似,因此,如果在此处使用setState,则需要在某些时候进行限制,如下所示:
  • useEffect is similar to componentDidMount and componentDidUpdate, so if you use setState here then you need to restrict at some point 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆