質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

3回答

1020閲覧

async, awaitのコードを関数化すると、json()使用しているのに返り値がPromiseになる

kazoogon

総合スコア281

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2019/06/25 01:28

編集2019/06/26 07:26

環境

Amazon linux AMI
React.js 16.8.6
Typescript 3.5.2

実現したい事

▼現状(APIからjsonで情報を受け取る)

interface State { products: any[], } class Hoge extends React.Component<{}, State> { constructor(props: any) { super(props); this.state = { products: [] }; } async componentDidMount() { //=====ここのAPIの情報とってくる部分を関数化したい===== const response = await fetch('/api/hoge', { method: POST, }); const products = await response.json(); this.setState({ products }); } render() { return ( <div className="hoge"> //省略 </div> ); } } export default Hoge;

▼試してみたコード

import apiConnect from '../common/ApiConnect';//**追加 interface State { products: any[], } class Hoge extends React.Component<{}, State> { constructor(props: any) { super(props); this.state = { products: [] }; } async componentDidMount() { const products = apiConnect('/api/hoge', 'POST')//**変更 this.setState({ products }); } render() { return ( <div className="hoge"> //省略 </div> ); } } export default Hoge;

▼apiConnect.tsx

const apiConnect = async function(url: string, method: string) { const response = await fetch(url, { method: method, }); const data = await response.json(); return data; } export default apiConnect;

困っていること、質問

①apiConnect関数ではjson()を使用しているのに、Promiseがreturnされるのはなぜか?
②①のせいでsetStateで値を更新できないが、この場合どう対処したら良いのか?

よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2019/06/25 01:46

表題「async」のつづりが違います
guest

回答3

0

asyncはpromiseを返す仕様です
戻り値はthenのコールバックの引数で確認してください

javascript

1const x=async ()=>await [1,2,3]; 2x().then(console.log);

投稿2019/06/25 01:42

編集2019/06/25 01:45
yambejp

総合スコア114896

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazoogon

2019/06/26 08:44

ご回答ありがとうございます。 こちら参考に自分でapiConnect関数を修正したらいけました、ありがとうございます。
guest

0

自己解決

apiConnect関数呼び出し部分にawaitを追加したらいけました

投稿2019/06/26 08:42

編集2019/06/26 11:13
kazoogon

総合スコア281

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KuwabataK

2019/06/26 10:02

純粋に興味なのですが、上記の修正って意味あるのでしょうか・・・? もとのapiConnect()関数のまま、apiConnect()を呼び出すときにawaitをつけるだけで動きませんか?
kazoogon

2019/06/26 10:22

そうするとthis.setState({ products });の部分でpruductがPromiseだからsetStateできないよ。というエラーが返ってきます。 (もしエラー文が必要な場合はご連絡くださいませ)
KuwabataK

2019/06/26 10:47

確認したいのですが、apiConnect()関数の呼び出し部分は const products = apiConnect('/api/hoge', 'POST') と書いていますか?それとも const products = await apiConnect('/api/hoge', 'POST') と書いていますか? 下の書き方で動くのであればわかるのですが、上の書き方のままで動くのであれば、私のPromiseの理解が間違っている気がして気になりました。 そこだけ確認していただければ、後は自分で調べたいと思います。 付き合わせてしまって申し訳ないです
kazoogon

2019/06/26 10:56

const products = await apiConnect('/api/hoge', 'POST') とawaitを追記する + apiConnectの関数内を修正する でいけました。
KuwabataK

2019/06/26 11:03 編集

あ、そうなのですね。良かったです。 じゃあ試しにapiConnectの中身を変えずに awaitだけ追記したコードを試してみてください 多分動きますよ apiConnectの中身は最初のまま(以下のまま)で問題ないです const apiConnect = async function(url: string, method: string) { const response = await fetch(url, { method: method, }); const data = await response.json(); return data; }
kazoogon

2019/06/26 11:10

あ、確かに動きました。 関数は元々json返していたけど、setStateをするのがまだAPIから情報をとってきていない時点だった。 ということですね(=だからawait付けて、productsにAPIからの値が入ったあとにsetStateする)
kazoogon

2019/06/26 11:12

また全く違う質問になるんですが、これ関数名apiConnectよりapiFetchの方がいいのかなぁ と思ってきました。 もしお時間余裕ありましたら、ご意見お伺いしたいです
kazoogon

2019/06/26 11:14

ベストアンサーにkuwataKさん指定したいですが、もう手遅れで申し訳ないです汗
KuwabataK

2019/06/26 11:24 編集

いえいえ、大丈夫ですよ。 私もPromiseやasync/awaitの仕様を再確認できたので良かったです。 名前の件ですが、私的にはapiConnectのまんまでもいいかな。と思います。 理由は、fetchという名前だとデータをダウンロードするイメージをもつ人がいる(たぶんGitの影響)ということですね。今回のapiConnect()は引数にmethodを指定できるようになっていてPOSTリクエストとかも送れるので、そこで混乱する人も(もしかしたら)いるかもなあ と思いました。 とはいえ、標準APIでPOSTもPUTも呼べるfetchAPIがあるので、そちらをきちんと理解して連想してくれるメンバーと仕事できるならfetchのほうがいいですね。 まあ殆ど好みの差なのでどちらでも良いと思います。
kazoogon

2019/06/26 11:33

いろいろご丁寧なご回答ありがとうございました。 他の方の意見が聞けてよかったです :)
KuwabataK

2019/06/26 11:34

と、書いた後に気づきましたが、apiConnectはデータを持ってくる用の関数として考えていて、送信は考慮してない感じですかね? それならapiFetchのほうが、データをもらってくる用だよ感がでて良いと思います
guest

0

他の回答でも言われているようにasync関数はPromiseを返します。
そしてPromiseを返すということは、他のasync関数内で使う場合にはawaitを使うことができるということです。

なので、以下のようなコードに変更すれば動くと思います

js

1async componentDidMount() { 2 const products = await apiConnect('/api/hoge', 'POST') // <= awaitをつける 3 this.setState({ products }); 4}

投稿2019/06/25 04:30

KuwabataK

総合スコア306

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazoogon

2019/06/26 08:43

ご回答ありがとうございます、こちらの修正と関数の中身を変更したらいけました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問