🐕

React コンポーネントのレンダリングと副作用について

2024/06/24に公開

はじめに

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