初心者のプログラミング日記

プログラミング初心者の日記

プログラミングに関することを書いていきます。

useEffectでわからなかった所

useEffectを使う時にちょっとわからなかった事があったので、そのメモ用です。
まず、前提としてuseEffectはコンポーネントレンダリングが終わってから実行されます。
そして、第2引数で実行タイミングを決めます
この時の私はこのことも知らなかったです。

console.log(”マウント”);
const [user, setUser] = useState([]);
useEffect(() => { getUser() }, [])
const getUser = async () => {
        console.log(”実行中”);
        const response = await axios.get('/api/user');
        setUser(response.data);
  //response.data [{id:1,name:"太郎"}]
       console.log(”完了”);
}
console.log(user);

とりあえず、こんな感じでデータをセットします。
これでログを確認すると

マウント
undefined
実行中
マウント
[{id:1,name:"太郎"}]
成功

環境によってはundefinedが[]だったりするのですが、特に気にしなくていいです。
大体こんな感じだと思います。

自分はこの時初めて知ったのですが、今回のようにresponse.dataが配列で、userの初期値も空配列なので多次元配列になると考えていたのですが、普通の連想配列になるようです。

[[{id:1,name:"太郎"}]]      ✕
[{id:1,name:"太郎"}]  ○

でここからuserの値を取り出すのですが、userの初期値がから配列なのでconsole.log(user.id);とすると

マウント
undefined //ここでUncaught TypeError: Cannot read property 'id' of undefined になる
実行中
マウント
[{id:1,name:"太郎"}]
成功

とエラーがでます。
当たり前なんですけど、初期値が空配列なのでidなんかないんですよね。
idが入るのはuseEffect実行後、つまりコンポーネントレンダリングが終わってからなので、1回目のレンダリングの時点ではconsole.log(user.id);はエラーになります。

なので

const id = user.map(item => item.id);

map関数を使えばエラーにならず値を取り出すことができます。