[解決済み] Reactの関数型コンポーネントでasync/awaitを使用する
質問
私はプロジェクトでReactを使い始めたばかりですが、あるコンポーネントにasync/await機能を組み込むのにとても苦労しています。
という非同期関数があります。
fetchKey
という非同期関数があり、AWS API Gateway経由で提供している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テーマを使っており、その中の1つのDashboardテンプレートを使いたいと考えていました。残念ながら、ダッシュボード テンプレートは、機能的なステートレス コンポーネントを使用しています。
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
. どーん。そのため、実際のプロミスが解決されているにもかかわらず、結果が未定義として返されていたのです。
どのように解決するのか?
次の2つを確認する必要があります。
-
useEffect
はcomponentDidMount
とcomponentDidUpdate
を使用するとsetState
として使用する場合は、コードの実行を制限する必要があります。componentDidUpdate
として使用する場合は、どこかでコードの実行を制限する必要があります。
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
);
}
関連
-
[解決済み] forEachループでasync/awaitを使用する
-
[解決済み] Reactルータを使ったプログラムによるナビゲーション
-
[解決済み] React JSX内のループ
-
[解決済み] async」と「await」の使い方とタイミング
-
[解決済み] setStateを呼び出さずにReactコンポーネントを強制的に再レンダリングすることは可能ですか?
-
[解決済み] async/await関数を並列に呼び出す
-
[解決済み] Reactコンポーネント外でのクリックを検出する
-
[解決済み] 非同期関数+await+setTimeoutの組合せ
-
[解決済み] 複数のタスクにasync/awaitを使用する
-
[解決済み] CORS OriginヘッダーとCSRFトークンによるCSRF保護
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] AngularJSのエラーです。Cross Origin リクエストはプロトコルスキーム http, data, chrome-extension, https に対してのみサポートされています。
-
[解決済み] 配列からオブジェクトを生成する
-
[解決済み] 上級者向けJavaScript。この関数はなぜ括弧でくくられるのですか?重複
-
[解決済み] JavaScriptを使用してHTML要素に属性を追加/更新するには?
-
[解決済み] オブジェクトの配列からReactコンポーネントをレンダリングする
-
[解決済み] AJAX Mailchimp サインアップフォームの統合
-
[解決済み] 各オブジェクトに?重複
-
[解決済み] 文字列とラベルのローカライズとグローバリゼーションのベストプラクティス【終了しました
-
[解決済み] <ng-content>が空かどうかを確認する方法は?(これまでのAngular 2+で)
-
[解決済み] JavaScript で css プロパティを使用して HTML 要素の背景色を設定する方法