ReactのuseEffectとuseRefを組み合わせて非同期処理を管理する方法を初心者向けに解説
生徒
「先生、Reactで非同期処理をするときに、画面を移動した後も処理が動き続けてエラーが出ることがあります。どうすれば安全に扱えますか?」
先生
「そんなときには、useEffectとuseRefを組み合わせると便利です。非同期処理の状態をuseRefで保存して、キャンセルや制御ができるようにするんです。」
生徒
「useRefってDOM操作に使うものだと思っていました!」
先生
「確かにDOM要素を参照するときによく使いますが、実はコンポーネントの再レンダリングに影響しない変数を持ちたいときにも使えるんですよ。」
1. useRefで非同期処理を制御する意味
通常のuseStateを使うと値が変わるたびに画面が再レンダリングされます。しかし、非同期処理の状態管理では再レンダリングを必要としない場合が多いです。例えば「この処理がまだ有効かどうか」をチェックするだけなら、useRefを使うと効率的に扱えます。
初心者の方には少し難しく感じるかもしれませんが、簡単に言えば「メモを残しておく箱」がuseRefです。そして、そのメモを使って「もう処理を続けなくてもいい」と判断することができます。
2. useEffectとuseRefを組み合わせたサンプル
ここではサーバーからデータを取得するfetch処理を例にします。画面を閉じたときに不要な更新が走らないよう、useRefでフラグを管理します。
import React, { useEffect, useState, useRef } from "react";
function App() {
const [data, setData] = useState(null);
const isMounted = useRef(true);
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/posts/3")
.then((res) => res.json())
.then((result) => {
if (isMounted.current) {
setData(result);
}
});
return () => {
isMounted.current = false;
};
}, []);
return (
<div>
<h1>記事情報</h1>
{data ? <p>{data.title}</p> : <p>読み込み中...</p>}
</div>
);
}
export default App;
3. useRefを使うメリット
この方法を使うと、次のようなメリットがあります。
- 画面がアンマウントされた後に
setStateを呼び出すエラーを防げる - 余計な再レンダリングを避けられる
- 非同期処理の制御がシンプルに書ける
つまり、useRefは「安全に非同期処理を扱うためのお守り」のような役割を持っています。
4. 実際の開発で役立つ場面
実際のアプリ開発では、次のような場面でuseEffectとuseRefを組み合わせると効果的です。
- ログイン画面での認証リクエスト
- チャットアプリでの新着メッセージ取得
- 商品検索画面でのAPIリクエスト
これらの場面では、ユーザーが画面を移動することが多く、不要な非同期処理を止める仕組みが重要です。
5. 初心者が理解しておきたいポイント
初心者の方が混乱しやすいのは、「useRefはレンダリングに影響を与えない変数」という点です。つまり、値を変えても画面は更新されません。そのため、状態管理と見た目の更新はuseState、処理の制御やフラグ管理はuseRefと使い分けることが大切です。
この違いを理解しておくと、Reactでの非同期処理やエラーハンドリングがぐっと楽になります。