目录
Hookの基本
「ReactのHookとは何か、なぜHookが導入されたのか?」
具体的な使用例:
たとえば、ToDoリストアプリを構築しているとします。Hookが導入される前では、ToDoリストの状態を保存するためにクラスコンポーネントを使用する必要がありました。Hookの導入により、useStateを利用したよりシンプルな関数コンポーネントで同じ機能を実現できるようになりました。
Hook導入前:クラスコンポーネントの利用
Hookが登場する前は、コンポーネント内で状態を利用したい場合、通常クラスコンポーネントを使用していました。以下に、クラスコンポーネントを使用してToDoリストを実装する例を示します。
核心的な概念:
-
状態(state) は
this.stateで定義され、それはオブジェクトです。 -
状態の更新 は
this.setState()メソッドを使用して行われます。 - コンポーネントの振る舞い(ユーザー入力の処理やフォームの送信など)は、コンポーネント内のメソッド(例:
handleInputChangeやhandleSubmit)で定義されます。 - これらのメソッドは
thisに正しくバインドする必要があり、さもなければthis.stateやthis.setStateにアクセスできません。
import React from 'react';
class TodoList extends React.Component {
constructor(props) {
super(props);
this.state = {
todos: [],
newTodo: ''
};
}
handleInputChange = (e) => {
this.setState({ newTodo: e.target.value });
};
handleSubmit = (e) => {
e.preventDefault();
if (!this.state.newTodo) return;
const newTodo = {
text: this.state.newTodo,
isCompleted: false
};
this.setState({
todos: [...this.state.todos, newTodo],
newTodo: ''
});
};
}
export default TodoList;
Hook導入後:関数コンポーネントと useState の利用
Hookを導入した後は、よりシンプルな関数コンポーネントを使用して同じ機能を実現できます。以下に、useState Hookを利用して実装された同じToDoリストの例を示します。
核心的な概念:
-
状態(state) は
useStateHookを通じて定義されます。各状態は独立した変数であり、オブジェクトの属性ではありません。 -
状態の更新 は
useStateで返される状態設定関数を呼び出すことによって行われます。 - コンポーネントの振る舞い(ユーザー入力の処理やフォームの送信など)は、コンポーネント内の関数を通じて定義されます。
- クラス内での
thisの問題を気にする必要がなくなります。なぜなら、あなたはもはやクラスの中ではなく、関数の中にいるからです。
import React, { useState } from 'react';
function TodoList() {
const [todos, setTodos] = useState([]);
const [newTodo, setNewTodo] = useState('');
const handleInputChange = (e) => {
setNewTodo(e.target.value);
};
const handleSubmit =
(e) => {
e.preventDefault();
if (!newTodo) return;
const newTodoItem = {
text: newTodo,
isCompleted: false
};
setTodos([...todos, newTodoItem]);
setNewTodo('');
};
}
export default TodoList;
useStateというHook
React関数コンポーネントでuseStateを使用して状態を管理する方法は?
useStateは、Reactの関数コンポーネントで状態を追加するためのHookです。使用方法は非常に簡単です。useStateを呼び出し、初期状態を渡すだけです。useStateは配列を返し、その第一要素は現在の状態の値、第二要素はその状態を更新する関数です。
具体的な使用例:
カウンターアプリを構築しているとします。useStateを使用して、現在のカウントを保存できます:
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
この例では、countは現在の状態であり、setCountはその状態を更新する関数です。
useStateはどのように機能し、どのようにしてコンポーネントの再レンダリングを引き起こすのか?
useStateがどのように機能し、どのようにしてコンポーネントの再レンダリングを引き起こすのかを、日常生活の例で説明してみましょう。
useStateの概念
あなたが数字のスコアボードを持っていると想像してください。このスコアボードは現在のスコアを表示しています。あるボタンを押すたびに、スコアが増加します。このシナリオでは、スコアボードの表示が状態(ReactではuseStateで表現)であり、ボタンを押すことが状態を変更する行動に相当します。
ReactでのuseStateの使用
Reactでは、useStateは関数コンポーネント内で状態を追加するためのHookです。これを呼び出すと、2つの値が返されます:
- 現在の状態:これはスコアボードに表示されている現在のスコアに相当します。
- 状態を更新する関数:これはスコアを変更するためのボタンに相当します。
useStateを使って状態変数を定義するとき、初期値を与えます。スコアボードの例で言うと、初期スコアは0かもしれません。
const [score, setScore] = useState(0);
このコード行は何をしているのでしょうか?
- 新しい状態変数
scoreを宣言しています。 - 状態を更新するための関数
setScoreも提供しています。この関数を呼び出すことでscoreの値を変更できます。
コンポーネントの再レンダリングを引き起こす方法
例えば、スコアを1増やすボタンがあるとします。どうしますか?Reactでは、関数内でsetScoreを呼び出します。
function increaseScore() {
setScore(score + 1);
}
この関数が呼ばれるたびに、setScoreはscoreの状態を更新し、Reactにこのコンポーネントを新しいscore値で再レンダ
リングする必要があることを通知します。これは、スコアボードのボタンを押して、数字が更新された後、頭を上げて新しいスコアを確認することに似ています。ReactはUI上のスコアがコード内で保持している状態と一致するようにします。
useEffectというHookの使い方
日常生活での類似:
あなたが住んでいる家に温度調節器があると想像してください。この温度調節器は部屋の温度を監視し、調節します。もし部屋が暑すぎるか寒すぎると感知したら、それに応じて暖房や冷房を調節します。
Reactにおいて、useEffectはこの温度調節器のようなものです。データ取得、購読、またはDOMの手動変更などの副作用を実行することを可能にします。副作用とは、レンダリングの結果が画面に表示された後に発生することが期待される作業、例えばAPI呼び出し、タイマー設定、またはコンポーネントの振る舞いに影響を与える可能性のあるその他の操作のことを指します。
useStateとuseEffectの違いと分業
共通点:
- どちらもReactが提供するHooksであり、関数コンポーネントに機能を追加するために使用されます。
違い:
-
useStateは、コンポーネント内で状態変数を宣言するために使用されます。関数コンポーネント内で値を保存し、更新することができます。 -
useEffectは、副作用を扱うために使用されます。これには、APIリクエスト、購読、またはDOMの手動変更などが含まれます。
分業:
-
useStateはコンポーネントの状態の管理を担当します。 -
useEffectはコンポーネントの副作用を処理します。つまり、コンポーネントの出力に直接影響を与えない操作を担当します。
useEffectの依存配列
日常生活での類似:
あなたがスマートな電球を持っていると想像してください。この電球は、外部条件(時間、天候など)に応じてその明るさや色を変えることができます。例えば「夜になったら電球を暗くする」や「雨が降っていたら電球を青くする」といったルールを設定することができます。
useEffectでの依存配列は、これらのルールのようなものです。Reactに対して、配列内の値が変化したときにのみeffectを再実行するように指示します(これは、電球の色や明るさを再確認し、調整するようなものです)。
依存配列が空([])の場合、これはReactに「このeffectはコンポーネントがマウントされた時とアンマウントされた時に一度だけ実行する」と伝えます。依存配列を提供しない場合、コンポーネントがレンダリングされるたびにeffectが実行されます。
useEffectを使用してAPIを呼び出したりデータを購読したりする方法
日常生活での類似:
あなたがニュースサービスに購読していて、毎朝最新のニュースがあなたのスマートフォンに届けられると想像してください。このプロセスでは、購読する行為(リクエストを送る
)は朝に行われ、ニュースが届いた(データが届いた)ときに、あなたのスマートフォン(コンポーネント)が最新のニュースで表示を更新します。
Reactでは、useEffectを使用してこのようなパターンを実現できます。useEffectの関数内でAPIリクエストを行い、データが返されたときにコンポーネントの状態を設定します。
function NewsFeed() {
const [articles, setArticles] = useState([]);
useEffect(() => {
async function fetchData() {
const response = await fetch('<https://api.example.com/news>');
const data = await response.json();
setArticles(data.articles);
}
fetchData();
}, []); // 空の配列は、このeffectがコンポーネントがマウントされた時に一度だけ実行されることを意味する
return (
<div>
{articles.map(article => (
<p key={article.id}>{article.title}</p>
))}
</div>
);
}
この例では、コンポーネントが初めてレンダリングされたときにuseEffectが実行され、APIリクエストが行われます。リクエストからデータが返されたときにsetArticlesが呼び出され、コンポーネントの状態が更新されます。これにより、コンポーネントが再レンダリングされ、最新の記事が表示されます。