🐕
React コンポーネントのレンダリングと副作用について
はじめに
React の useEffect を学習中に、副作用について「副作用とは、コンポーネントのレンダリングに直接関係しないが、実行する必要がある処理のことを指す。」という説明を見て、そもそもコンポーネントのレンダリングについて理解が曖昧だったため、通常のレンダリングと、副作用の違いについて調べて整理してみます。
レンダリング とは
Reactがコンポーネントの内容をブラウザの画面に表示するプロセスのこと。
具体的には、次のような流れになります
初期レンダリング
- コンポーネントが最初にマウントされたときに、Reactはコンポーネントの
render
メソッドや関数コンポーネントの内容を実行し、その結果を仮想DOMに描画します。 - その後、仮想DOMと実際のDOMを比較し、必要な変更を実際のDOMに反映させます。
再レンダリング
- コンポーネントの状態(
state
)やプロパティ(props
)が変更されたときに再度実行されます。 - 変更された部分だけが仮想DOMに再描画され、必要な変更が実際のDOMに反映されます。
副作用とは
- 副作用は、コンポーネントのレンダリングとは直接関係しないが、実行する必要がある処理のことを指します。
レンダリングと副作用を比較してみる
レンダリング
-
レンダリングの役割:
- コンポーネントの見た目やUIを定義してブラウザに表示する。
-
実行タイミング:
- コンポーネントが最初にマウントされるとき。
- コンポーネントの状態(state)やプロパティ(props)が変更されたとき。
- 以下の例では、
text
プロパティの値がdiv
要素に表示される。これがレンダリングです。
function MyComponent({ text }) {
return <div>{text}</div>;
}
副作用
-
副作用の役割:
- コンポーネントの表示に直接関係しないが、必要な処理を行う。
-
実行タイミング:
- コンポーネントがマウントされた後。
- 依存する値が変更された後。
- コンポーネントがアンマウントされる前にクリーンアップを実行。
- 以下の例では、データをフェッチするという副作用が実行されます。
useEffect(() => {
// 副作用関数
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data));
}, []);
ユーザーのリストを表示するコンポーネントでの具体例
レンダリング:
- ユーザーのリストを表示する部分。
function UserList({ users }) {
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
副作用:
- ユーザーのデータをAPIからフェッチする部分。
- コンポーネントがマウントされたときに実行されます。
function App() {
const [users, setUsers] = useState([]);
useEffect(() => {
fetch('https://api.example.com/users')
.then(response => response.json())
.then(data => setUsers(data));
}, []);
return <UserList users={users} />;
}
まとめ
-
レンダリングとはコンポーネントのUIを定義し、それをブラウザに表示するプロセス。
- 実行タイミング: コンポーネントのマウント時、状態やプロパティの変更時。
-
副作用とはコンポーネントの表示に直接関係しないが、必要な処理(データフェッチ、タイマー設定、イベントリスナー追加など)。
- 実行タイミング: コンポーネントのマウント後、依存する値の変更後、アンマウント時のクリーンアップ。(クリーンアップ関数について別でuseEffect の記事で書く予定です)
Discussion