在React功能组件中使用async/await [英] Using async/await inside a React functional component
问题描述
我刚刚开始在项目中使用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
.这似乎向我表明该功能尚未完成,因此尚未解析data
或error
的任何值.但是,如果我尝试放置
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.
推荐答案
您将必须确保两件事
-
useEffect
与componentDidMount
和componentDidUpdate
类似,因此,如果在此处使用setState
,则需要在某些时候进行限制,如下所示:
useEffect
is similar tocomponentDidMount
andcomponentDidUpdate
, so if you usesetState
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屋!