web-dev-qa-db-ja.com

React機能コンポーネント内でasync / awaitを使用する

私はプロジェクトにReactを使用し始めたばかりで、コンポーネントの1つに非同期/待機機能を組み込むことに本当に苦労しています。

AWS API Gatewayを介して提供しているAPIからアクセスキーを取得して取得するfetchKeyという非同期関数があります。

_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のマテリアルUIテーマを使用しており、ダッシュボードテンプレートの1つを利用したいと思っています。残念ながら、ダッシュボードテンプレートは機能的なステートレスコンポーネントを使用します。

_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)の結果は期待どおりですが、GoogleのスクリーンショットChromeブラウザは多少矛盾しています-保留中ですか、それとも解決されますか?- 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_メソッドを使用して状態を設定し、その後、陽気な方法で進みます。しかし、それはありません。この機能コンポーネントのオプション。

機能Reactコンポーネントに非同期/待機ロジックを組み込むにはどうすればよいですか?

編集:だから私はばかだとだけ言います。返される実際の応答オブジェクトは_response.data.access_token_ではありません。 _response.data.Item.access_token_でした。どー!そのため、実際の約束は解決されましたが、結果は未定義として返されていました。

16
Yu Chen
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

0