やあ、こんにちは。Reactの世界へようこそ。
日々コードを書いていると、「あれ?なんか思った通りに動かないな」「画面がチラつく気がする」なんてことは日常茶飯事です。特に、Reactを学び始めて最初にぶつかる大きな壁が、この`useEffect`の使い道なんですよね。
今日は、多くの人がついやってしまいがちな「データの変換」に関する、ちょっとした罠についてお話しします。大丈夫、ここで立ち止まるのは、あなたがReactを深く理解しようとしている証拠ですよ。
—
犯人は「useEffectで計算しちゃう」という癖
例えば、あなたが「お買い物の合計金額」を表示するアプリを作っているとしましょう。
商品がカートに入っていて、その個数と単価を掛け合わせて、最後に割引を適用して……という処理ですね。
初心者の頃、こんなふうに書いてしまったことはありませんか?
const [price, setPrice] = useState(1000);
const [count, setCount] = useState(1);
const [total, setTotal] = useState(0); // 頑張って計算結果を入れる箱を作っちゃう
useEffect(() => {
// priceやcountが変わるたびに計算して、stateを更新する
setTotal(price count);
}, [price, count]);
一見、「お、動いてる!」と思いますよね。でも、実はこれ、「Reactの魔法」をわざわざ打ち消すような、少しもったいない書き方なんです。
なぜこれが「アンチパターン」なのか?
これを身近な例えで説明しますね。
あなたは「ホワイトボード」に数字を書く係だと想像してください。
1. 理想的な状態(レンダリング中に計算):
ホワイトボードに「単価」と「個数」が書いてあれば、見る人は一瞬で「あ、合計はこれだな」と頭の中で計算できますよね? これがReactのやり方です。
2. useEffectを使う状態:
「単価」と「個数」が書き換わるたびに、わざわざ「計算用のペン」を持って、別の場所に「合計」を書き直している状態です。
これだと、「数字が変わる」→「一旦レンダリング」→「useEffectが走る」→「また計算して書き換える」→「もう一回レンダリング」という、二度手間が発生します。これでは画面がチラついたり、パフォーマンスが落ちたりするのは当然なんです。
—
解決策は「計算された値」をそのまま使うこと
Reactの哲学は「UIは状態(State)の関数である」というものです。つまり、「計算できるものは、わざわざState(状態)として保存しなくていい」のです。
修正後のコードを見てみましょう。驚くほどシンプルになりますよ。
const [price, setPrice] = useState(1000);
const [count, setCount] = useState(1);
// 【重要】useEffectを使わず、ただの変数として計算結果を持たせる!
// これなら、priceやcountが変わるたびに、この関数が実行される瞬間、
// 自動的に正しいtotalが計算されます。
const total = price count;
// これだけで、totalは常に最新の計算結果を保持しています。
// 画面に表示する時も、{total} と書くだけでOKです。
なぜこれでうまくいくの?
Reactは、コンポーネント内のコードを「毎回最初から最後まで読み直す」という性質を持っています。
`price`や`count`が更新されると、コンポーネントは「あ、値が変わったからもう一回作り直そう!」と動きます。そのとき、`const total = price count;` の行も当然実行されるので、常に最新の計算結果が手に入るというわけです。
—
「useEffect」は「魔法の杖」ではなく「最後の手段」
`useEffect`を使うべきなのは、計算のためではありません。
「Reactの世界から、外の世界へ影響を及ぼすとき」だけです。
- サーバーからデータを取ってくる(API通信)
- ブラウザのタイトルを書き換える
- タイマーをセットする
これらは「Reactの中だけでは完結しない処理」ですよね。こうした「副作用(Side Effect)」を扱うときこそ、`useEffect`の出番です。
—
最後に:つまずいても大丈夫
「useEffectで計算しちゃダメって言われたけど、これってどうすればいいの?」と悩んだら、こう自分に問いかけてみてください。
「これは、他の値から計算できるものかな?」
もし答えが「イエス」なら、迷わず`const`で作った変数に入れてしまいましょう。`useState`に保存する必要もなければ、`useEffect`で監視する必要もありません。
コードをシンプルに保つことは、Reactマスターへの最短ルートです。今日書いたそのコード、少しだけ「削ぎ落とす」意識を持ってみるだけで、驚くほど軽やかなアプリになりますよ。
また何か悩んだら、いつでも聞きに来てくださいね。一緒にコードを磨いていきましょう!

コメント