teratail header banner
teratail header banner
質問するログイン新規登録

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

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

新規登録して質問してみよう
ただいま回答率
85.30%
React.js

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

Q&A

解決済

2回答

2210閲覧

reactでuseEffectでREST APIを叩いて得たデータをpropsとして渡したい

asasaas

総合スコア26

React.js

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

0グッド

0クリップ

投稿2021/10/22 08:01

0

0

reactでuseEffectでREST APIを叩いて得たデータをpropsとして渡したい

useEffect内でapiを叩き、useStateを利用してresデータを保管したものをpropsで子コンポーネントに渡した時、子コンポーネント内のuseEffectではuseStateで初期値として設定した値が表示されてしまいます。
これを解決する方法はありますでしょうか?

js

1//Parent.tsx 2 3const Parent: React.FC = () => { 4 const [name, setName] = useState('takeshi') 5 6 useEffect(() => { 7 ;(async () => { 8 const res = await props.fetcher() //親コンポーネントでget処理記述 9 10 setName(res.data.name) //ここでhiroshiをsetできたとする 11 })() 12 }, []) 13 14 return ( 15 <Child name={name} /> 16 <p>{name}</p> //ここではhiroshi 17 )

js

1//Child.tsx 2 3const Parent: React.FC = (props) => { 4 const [name, setName] = useState('takeshi') 5 6 useEffect(() => { 7 setName(props.name) 8 }, []) 9 10 return ( 11 <p>{name}</p> //ここではtakeshi 12 )

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

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

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

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

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

guest

回答2

0

ベストアンサー

子コンポーネントのuseEffectの実行は子コンポーネントが初期化された時点で起こります。
するとまだ親コンポーネント内でのfetcher()が終わっていないため、初期値の"takeshi"props.nameに渡されて子コンポーネントのnameにセットされ、その後props.nameが変更されてもuseEffect(..., [])なので実行されず子コンポーネントのnameが初期値のままになっているのだと思います。

解決策としてはuseEffect()の第2引数にprops.nameを追記するか……

typescript

1//Child.tsx 2 3const Parent: React.FC = (props) => { 4 const [name, setName] = useState('takeshi') 5 6 useEffect(() => { 7 setName(props.name) 8 }, [props.name]) // 依存先にprops.nameを追加 9 10 return ( 11 <p>{name}</p> //ここではtakeshi 12 ) 13}

子コンポーネントでnameというStateを用意せずにprops.nameを使うかすればよいかと。

typescript

1//Child.tsx 2 3const Parent: React.FC = (props) => ( 4 <p>{props.name}</p> // 単純にprops.nameを使う 5)

個人的には子コンポーネント内でStateを持つと同じ値を2つのコンポーネントで同時に状態管理するといういびつな形になってしまうので、状態管理は親コンポーネントに任せて子コンポーネントは値を使うだけの2つ目の方法がおすすめです。

投稿2021/10/22 09:38

編集2021/10/22 09:42
fj68

総合スコア752

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

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

asasaas

2021/10/22 09:44

子コンポーネント内で受け取った値を変更する必要があったので、前者で対応しうまく動作しました。ありがとうございます。
guest

0

「値が揃うまでは子コンポーネントを表示しない(あるいは、ロード中のような表示にしておく)」ぐらいの方法しかありません。

async-awaitで書いているようにAPIリクエストは非同期処理なので、コンポーネントの最初の描画時に結果は得られません。

投稿2021/10/22 08:17

maisumakun

総合スコア146654

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

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

asasaas

2021/10/22 08:33

回答ありがとうございます。 Suspenseを使って待機用の子コンポーネントを表示しておくのようなイメージでしょうか。 親コンポーネント、子コンポーネントそれぞれでAPIリクエストをするのは一般的ではないですかね?
maisumakun

2021/10/22 08:35

> 親コンポーネント、子コンポーネントそれぞれでAPIリクエストをするのは一般的ではないですかね? 一般的であろうがなかろうが、「同期的に表示できない」という事実とは何ら関係しません。
asasaas

2021/10/22 08:42

実現したいこととして親、子コンポーネント両方でAPIからgetしたデータを表示したいの場合、同期的に表示できるようにする必要はありますか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問