web-dev-qa-db-fra.com

Utiliser async / wait dans un composant fonctionnel React

Je commence tout juste à utiliser React pour un projet, et j'ai vraiment du mal à incorporer la fonctionnalité async/wait dans l'un de mes composants.

J'ai une fonction asynchrone appelée fetchKey qui va et obtient une clé d'accès d'une API que je sers 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;
  }
};

J'utilise le thème de l'interface utilisateur de React et j'ai décliné pour utiliser l'un de ses modèles de tableau de bord. Malheureusement, le modèle Dashboard utilise un composant sans état fonctionnel:

const Dashboard = props => {
  const classes = useStyles();

  const token = fetchKey(props.auth);
  console.log(token);

  return (
  ... rest of the functional component's code

Le résultat de ma console.log(token) est une promesse, ce qui est attendu, mais la capture d'écran dans mon navigateur Google Chrome navigateur est quelque peu contradictoire - est-elle en attente ou est-elle résolue? - enter image description here

Deuxièmement, si j'essaie à la place token.then((data, error)=> console.log(data, error)), j'obtiens undefined pour les deux variables. Cela semble m'indiquer que la fonction n'est pas encore terminée et n'a donc résolu aucune valeur pour data ou error. Pourtant, si j'essaie de placer un

const Dashboard = async props => {
  const classes = useStyles();

  const token = await fetchKey(props.auth);

React se plaint puissamment:

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

Maintenant, je serai le premier à déclarer que je n'ai pas assez d'expérience pour comprendre ce qui se passe avec ce message d'erreur. S'il s'agissait d'un composant de classe React React traditionnel, j'utiliserais la méthode this.setState Pour définir un état, puis continuer ma joyeuse façon. Cependant, je n'ai pas cette option dans ce composant fonctionnel.

Comment intégrer la logique asynchrone/wait dans mon composant fonctionnel React?

Edit: Donc je vais juste dire que je suis un idiot. L'objet de réponse réel qui est renvoyé n'est pas response.data.access_token. C'était response.data.Item.access_token. Ah! C'est pourquoi le résultat a été renvoyé comme indéfini, même si la promesse réelle a été résolue.

16
Yu Chen
const token = fetchKey(props.auth);

Cela renvoie une promesse. Pour en obtenir les données, voici une façon de procéder:

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

Faites-moi savoir si cela fonctionne.

J'ai recréé un exemple similaire: https://codesandbox.io/embed/quiet-wood-bbygk

0
Praneeth Paruchuri