Reactでは、Reactコンポーネントの記述方法が2つあります。
- 関数を使用するFunction Component(関数コンポーネント)
- クラスを使用するClass Component(クラスコンポーネント)
2019年にReact 16.8に「Hooks」が導入され、関数コンポーネントの使用が増加しています。
今回は、なぜ関数コンポーネントの使用が増加しているのか?関数コンポーネントとクラスコンポーネントの違いは?について解説します。
Componentとは
Componentとは、UIの一部をパーツ化して切り出すことができる機能です。
ページのUIを適度な粒度のコンポーネントに分解することで、可読性が上がり再利用性が増します。
コンポーネントは以下のように書きます。(※関数コンポーネントの例)
import React, { Component } from 'react';
class Test extends Component {
render() {
return <p>Hello!</p>;
}
}
export default Test;
上記で作成したコンポーネントを使う場合は、以下のように呼び出します。
import React from 'react';
import ReactDOM from 'react-dom';
import Test from './Test';
ReactDOM.render(
<Test/>,
document.getElementById('root')
);
<Test/>と記述するだけで、任意のページで呼び出すことが可能です。このように、簡単に使うことができ、可読性と再利用性に優れていることが分かります。
Class componentとFunction componentの違い
では具体的にClass componentとFunctional componentの違いを解説します。結論、大きな違いは「コード量」です。
具体的にコード量がどのように違うのかコンポーネントを主に使用する以下3つから違いを見ていきます。
- JSX
- Props
- State
JSX
JSXとは、React要素をHTML形式に似た構文で書くことができる、JavaScriptを拡張したものです。
JSXを使うことによって、簡便にReactを扱うことが可能です。では、実際にJSXを利用する各コンポーネントでの記述方法を確認しましょう。
関数コンポーネントの記述
関数コンポーネントは、JSXを返すプレーンなJavaScript関数なので、JavaScriptの標準的な関数と同じような記述が可能です。
import React from "react";
const FunctionComponent = () => {
return <h1>Hello, React</h1>;
};
クラスコンポーネントの記述
クラスコンポーネントは、React.Componentを拡張するJavaScriptクラスです。ES6に沿った記述をします。
import React, { Component } from "react";
class ClassComponent extends Component {
render() {
return <h1>Hello, React</h1>;
}
}
Props
Propsとは、コンポーネントに属性として設定ができる値のことを指します。簡単に説明すると、親コンポーネントから子コンポーネントへ値を渡すための仕組みのことです。
Propsは一度セットすると値の変更ができません。
では、実際にPropsを利用した各コンポーネントでの記述方法を確認しましょう。
以下のコード例では「TARO」という名前のpropsを受け渡しています。
関数コンポーネントの記述
関数コンポーネントでは、引数としてPropsの引き渡しが可能です。
<FunctionComponent name="TARO" />
const FunctionComponent = (props) => {
return <h1>Hello, {props.name}</h1>;
};
「FunctionComponent」を呼び出した際に、引数からpropsを受け取っています。
非構造化を使用した記述だと以下のようになります。
<FunctionComponent name="TARO" />
const FunctionComponent = ({props}) => {
return <h1>Hello, {name}</h1>;
};
非構造化の記述方法だと、直接props名を指定して値を受け取ることが可能です。
クラスコンポーネントの記述
<Component name="TARO" />
class ClassComponent extends React.Component {
render() {
const { name } = this.props;
return <h1>Hello, { name }</h1>;
}
}
クラスコンポーネントの場合、thisを使用してpropsを参照する必要があります。
State
Stateとは、各コンポーネントごとにコンポーネント内の状態を管理する仕組みのことです。コンポーネント利用時に値を設定することができ、Stateは後から値の変更が可能です。
最近まで、クラスコンポーネントのみでstateは使用可能でしたが、React 16.8でReact Hook useStateが登場してから関数コンポーネントでも記述が可能になりました。
では、実際にStateを利用した各コンポーネントでの記述方法を確認しましょう。
以下のコード例では「クリックするとカウント数が増えるカウンター」を例にstateの記述方法を解説します。
関数コンポーネントの記述
今回のState名は「count 」です。「button onClick」されたら「count」のStateが増えていく仕組みになっています。
const FunctionComponent = () => {
const [count, setCount] = React.useState(0);
return (
<div>
<p>count: {count}</p>
<button onClick={() => setCount(count + 1)}>Click</button>
</div>
);
};
関数コンポーネントでstate変数を使用するには、初期状態の引数を取るuseStateフックを使用する必要があります。
今回は、Stateのcountには初期状態として0を初期セットをしています。
クラスコンポーネントの記述
class ClassComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
render() {
return (
<div>
<p>count: {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click
</button>
</div>
);
}
クラスコンポーネントでのstateを処理する場合、関数コンポーネントと概念は同じですが構文が異なります。
関数コンポーネントを使用するメリット
「JSX・Props・State」の記述方法を比較してわかったように、関数コンポーネントを使用する大きなメリットは構文の短さです。
今回のコード例は、記述量が少ないため、あまり魅力的に感じなかったかもしれませんが、1000行以上〜などになると、構文の短さや可読性の高さが明確に現れてきます。
以前は「State・Lifecycle」がクラスコンポーネントでしか使用することのできない機能でした。しかし、゙React Hooks の登場により、関数コンポーネントでも扱うことが可能となりました。
そのため、関数コンポーネントを使用した記述方法がメジャーになってきています。
参考資料
関数コンポーネントとクラスコンポーネントを更に詳しく知りたい方は、公式ドキュメントから確認可能です。
まとめ
今回は、関数コンポーネントとクラスコンポーネントの違いについて解説しました。
全体的に関数コンポーネントを推している内容となっていますが、クラスコンポーネントにもメリットは存在します。
しかし、構文の短さ・可読性の高さを考慮すると関数コンポーネントがメジャーになりつつある理由に納得します。
また、ReactチームがReact Hooksの開発・サポートを重点的に行っていることもあり、関数コンポーネントを使う機会が、今後一層増すと考えられます。