副作用とは

副作用とは

React のコンポーネントの仕事は1つだけです。いまの props と state から、画面の形を作って返すことです。同じ入力なら同じ結果を返す、この性質を純粋と呼びます。

ところが、アプリには画面を作るだけでは終わらない仕事があります。たとえば次のようなものです。

  • ブラウザのタブのタイトル (document.title) を書きかえる
  • setInterval でタイマーを動かす
  • サーバーにデータを取りに行く
  • localStorage に保存する

どれも React が管理している画面の外に触っています。このように、描画そのものではない仕事のことを 副作用 と呼びます。副作用は悪いものではありません。アプリに必要な仕事です。大事なのは「どこに書くか」です。

レンダーの途中で外に触らない

いちばんやりがちな失敗が、コンポーネントの本体に副作用をそのまま書くことです。

import { useState } from "react"; export default function App() { const [likes, setLikes] = useState(0); // これは書いてはいけない場所 document.title = `いいね ${likes}`; return <p>いいね {likes}</p>; }

コンポーネントの本体は「画面を作る式」であって、いつ何回呼ばれるかは React が決めます。開発中は同じ描画が2回走ることもあります。ここに外の世界を触る処理を置くと、走る回数も順番も自分では読めなくなります。

副作用を書く場所は2つ

きっかけで置き場所が決まります。

  • ユーザーの操作がきっかけのもの ... イベントハンドラーの中に書く
  • 画面に表示されたこと自体がきっかけのもの ... useEffect の中に書く (次のレッスン)

今回は前者を練習します。ボタンを押したときに起きる仕事なら、onClick に渡す関数の中が正しい置き場所です。

つまずきどころ

setLikes(likes + 1) のような state の更新は副作用ではありません。React の内側の話なので、イベントハンドラーの中でそのまま呼んで大丈夫です。「外に触っているか」で見分けてください。

演習

レンダーの途中でタブのタイトルを書きかえてしまっているコードを直します。

ヒント

App.jsx
App.jsx
プレビュー

できているか

  • h1 に「あおいのプロフィール」と表示されている
  • 最初は「記録 0 件」と表示されている
  • いいねボタンを押すと、いいね数と記録件数の両方が増える