我刚刚开始将 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)
的结果是一个 Promise,这是意料之中的,但我的 Google Chrome 浏览器中的屏幕截图有些矛盾 - 它是待定的,还是已解决?
其次,如果我改为尝试 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
方法来设置一些状态,然后继续我的快乐之路。但是,我在这个功能组件中没有那个选项。
如何将异步/等待逻辑合并到我的功能性 React 组件中?
编辑: 所以我只想说我是个白痴。返回的实际响应对象不是 response.data.access_token
。它是 response.data.Item.access_token
。呸!这就是为什么结果返回为未定义的原因,即使实际承诺已解决。
原文由 Yu Chen 发布,翻译遵循 CC BY-SA 4.0 许可协议
你必须确保两件事
useEffect
is similar tocomponentDidMount
andcomponentDidUpdate
, so if you usesetState
here then you need to restrict the code execution at some point when用作componentDidUpdate
如下图: