ReactNativeのuseEffectの使い方とは?徹底解説
「useEffectを使ってたら、止まらなくなった。」
「なんで止まらなくなった、なんで動いてるの?」
今回は、useEffectの使い方を解説します。初心者でよくあるのが、useEffectを使っていると、処理が止まらなくなることがあります。
useEffectをどうやって使えば良いか、また、どのような場合に使えば良いかを解説していきます。
コードも交えて解説していきますので、ぜひこれからReactNativeを勉強していこうと思っている方は参考にしてみてください。
目次(クリックで読みたい部分にジャンプできます)
useEffectとは
useEffectの中に書いた内容は画面が表示されるたびに、実行されます。
useStateとは違い、戻り値は持たず、関数を登録して実行タイミングを管理するメソッドとなっています。
まずは、一番簡単な使い方を紹介します。
export default function App() {
useEffect(() => {
alert('hello');
})
return (
<View>
<Text>Hello!</Text>
</View>
);
};
useEffectがなければ、ただHello!を表示するだけのものですが、useEffectを書くと画面が表示される時に、useEffectに書かれている関数(今回はアラート)が実行されます。
useEffectの実行タイミングが結構ややこしくて、上のような単純な構文なら良いのですが、複雑なものになると、よく処理が止まらなくなることがあります。そんなときの対処法を次章で紹介します。
useEffectの実行タイミングは関数が実行された時
関数コンポーネントが実行されるたびに毎回実行されます。
まずこれをよく覚えておきましょう。useEffectを使うときに処理が止まらなくなる原因の大部分がこの性質が使われています。
そんな時にuseEffectのパラメーターを監視して渡されたかんすの実行を制限する機能を使います。これを利用するには、第2引数にパラメーターの配列を登録します。例えば、次のコードのようにpropsで渡されたIDを元に、表示するデータをとってくる処理について考えます。
const [data, setData ] = useState(null);
useEffect(() => {
fetch(`https://example.com/api/data?id=${props.dataId}`)
.then(res => res.json())
.then(_data => setData(_data));
}, [props.dataId]);
こちらのコードで重要なことは、[props.dataId]の部分です。
useEffectは本来なら、関数が実行されたときに毎回実行されるものですが、[props.dataId]を第2引数に書くことによって、props.dataIdのみを監視し、props.dataIdが更新された時にのみuseEffetの関数の中身を実行することができるのです。
そして、useEffectと一緒に記載してある、useStateが、useEffectが実行されるたびに実行されるので、変数dataの中身が更新されていきます。
これは、画面を最新に更新するために、よく使われる方法です。useEffectで変数を監視し、変数が変更される(変数の中身が最新になる)と同時に、useStateを用いて、画面の中で使われている変数を更新していく流れです。
useStateについて詳しく知りたい方は以下の記事を参考にしてみてください。
【注意点】フックを条件分岐で呼び分けてはいけない
useStateやuseEffectはまとめて、フックと呼ばれています。
これらには初心者がハマりやすい注意点があります。それは「フックの実行を条件分岐やループに入れてはいけない」ということです。
例えば、以下のコードのように、未ログインだった場合にログイン処理を実行させたいと思ったら、このように書くでしょう。
const [loginState, setLoginState] = useState(null);
if (!loginState){
useEffect(() => {
api.login("...")
.then(result => setLoginState(result));
});
}
これは、実行するときにreactが正しい挙動をできなくなる、誤った書き方です。Reactはフックの種類と呼び出し順を覚えることでフックの状態を管理しているので、条件分岐やループで呼び出し順が変わってしまうと困るのです。正しくは次のように書きます。
const [loginState, setLoginState] = useState(null);
useEffect(() => {
if(!loginState) {
api.login("...")
.then(result => setLoginState(result));
}
});
このように、if文は必ずuseEffectの中に書くことが大事です。これは独自フックを作る場合でも土曜で、関数がフックを呼び出す順番が一定になるようにしましょう。とりあえず、useEffectの外に条件分岐を書いてはいけない!ということを覚えておきましょう。
まとめ
今回はuseEffectについて解説しました。アプリ作成をしていると、useEffectの暴走はよくあります。状態を管理してくれるのでとても便利に使えますが、使い方には十分注意して使うようにしましょう。