代码之家  ›  专栏  ›  技术社区  ›  Yu Chen little_birdie

在react功能组件中使用async/await

  •  0
  • Yu Chen little_birdie  · 技术社区  · 5 年前

    我刚刚开始在项目中使用react,并且正在努力将async/await功能集成到我的一个组件中。

    我有一个异步函数 fetchKey 然后从我通过aws api网关提供的api获取访问密钥:

    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主题,并希望使用它的一个仪表板模板。不幸的是,仪表板模板使用了一个功能性的无状态组件:

    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) 是一个承诺,这是意料之中的,但我的谷歌浏览器中的屏幕截图有点矛盾-是悬而未决,还是解决了? enter image description here

    第二,如果我试着 token.then((data, error)=> console.log(data, error)) ,我明白了 undefined 对于这两个变量。这似乎表明函数尚未完成,因此没有解析 data error . 但是,如果我试着

    const Dashboard = async props => {
      const classes = useStyles();
    
      const token = await fetchKey(props.auth);
    

    React强烈抱怨:

    > 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 方法设置一些状态,然后继续我的快乐之路。但是,在这个功能组件中我没有这个选项。

    如何将异步/等待逻辑合并到功能反应组件中?

    编辑: 所以我只能说我是个白痴。返回的实际响应对象不是 response.data.access_token . 它是 response.data.Item.access_token . 呸!这就是为什么返回的结果是未定义的,即使实际的承诺已经解决。

    2 回复  |  直到 5 年前
        1
  •  0
  •   Praneeth Paruchuri    5 年前
    const token = fetchKey(props.auth);
    

    这是一个承诺。要从中获取数据,这是一种方法:

    let token = null;
    fetchKey(props.auth).then(result => {
      console.log(result)
      token = result;
    }).catch(e => {
      console.log(e)
    })
    

    如果可以的话告诉我。

    我重新创建了一个类似的示例: https://codesandbox.io/embed/quiet-wood-bbygk

        2
  •  1
  •   Tan Dat    5 年前

    使用react钩子,现在可以实现与函数组件中的类组件相同的功能。

    import { useState, useEffect } from 'react';
    
    const Dashboard = props => {
      const classes = useStyles();
      const [token, setToken] = useState(null);
      useEffect(() => {
         async function getToken() {
             const token = await fetchKey(props.auth);
             setToken(token);
         }
         getToken();
      }, [])
    
    
      return (
      ... rest of the functional component's code
      // Remember to handle the first render when token is null
    

    另外请看一下: Using Async await in react component