こんにちは
以下は、公式ドキュメントから引用した、useEffectの説明です。
useEffect は毎回のレンダー後に呼ばれるのか? その通りです! デフォルトでは、副作用関数は初回のレンダー時および毎回の更新時に呼び出されます。あとでカスタマイズする方法について説明します。「マウント」と「更新」という観点で考えるのではなく、「レンダーの後」に副作用は起こる、というように考える方が簡単かもしれません。React は、副作用が実行される時点では DOM が正しく更新され終わっていることを保証します。
上記により、 一回目のuseEffect
は初回のレンダーの後に呼ばれます。従って、初回のレンダーが行われる時点では、ご質問のコードにある userData
は、useState()
に引数を与えていないので、undefined
になります。初回のレンダーの後、useEffect
が呼ばれて、AddUserData()
が呼ばれ、setUserData()
が呼ばれて、2回目のレンダー時では、userData
に値が入っています。
以下は、ご質問にあるコードに多少修正を加えて、2回目のレンダー時には userData
に値が入っていることを確認するサンプルコードです。
jsx
1// dummy data
2const guestInformations = [
3 { id: 1, name: 'foo' },
4 { id: 2, name: 'bar' },
5 { id: 3, name: 'baz'}
6];
7const personal_info = { userId: 2 };
8
9// redering counter
10let counter = 0;
11
12const App = () => {
13 const [userData, setUserData] = useState();
14
15 const AddUserData = () => {
16 const userInfo = guestInformations.find(doc => doc.id === personal_info.userId);
17 setUserData(userInfo);
18 }
19
20 useEffect(() => {
21 AddUserData();
22 }, []);
23
24 console.log(`render#${++counter}: ${JSON.stringify(userData)}`)
25
26 return (<div>{JSON.stringify(userData)}</div>);
27}
Console に
render#1: undefined
render#2: {'id':2,'name':'bar'}
と出力されるのが分かると思います。
上記のような挙動ではなく、初回のレンダー時から、有効な値の入った userData
を useState()
から返させたいということであれば、useState()
の引数として初期値を指定すればよいので、たとえば、以下のようにすればよいかと思います。
jsx
1 const userInfo = guestInformations.find(doc => doc.id === personal_info.userId);
2 const [userData, setUserData] = useState(userInfo);
上記のコードでは、 useEffect
および setUserData
を使っていないので、2回目のレンダーは発生せず、1回目のレンダー時から、userData
にはundefinedではない値が入っていることを確認できます。
以上、参考になれば幸いです。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。