Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
361 views
in Technique[技术] by (71.8m points)

javascript - Using async/await inside a React functional component

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

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;
  }
};

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

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? enter image description here

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

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.

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

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You will have to make sure two things

  • 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
  );
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...