上記の記事を読んで、コンポーネントについて整理。
コンポーネントは任意の入力を受け取り(props)、画面上に表示すべきReact要素を返す。
概念的には、JavaScriptの関数に似ている。
React要素についてはこちら
関数コンポーネントとクラスコンポーネント
関数コンポーネント
コンポーネントを定義する最もシンプルな方法はJavaScriptの関数を書くこと。(関数コンポーネント)
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
データの入ったpropsというオブジェクトを引数として受け取り、React要素を返すので、有効なReactコンポーネント。
クラスコンポーネント
ES6クラスも使用できる。
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
関数コンポーネントとクラスコンポーネントはReactの視点からは等価。
コンポーネントのレンダー
要素は、DOMのタグを表すReact要素以外にも、ユーザー定義のコンポーネントを表すこともできる。
const element = <div />
const element = <Welcome name="Sara" />;
props
Reactがユーザ定義のコンポーネントを見つけた時、JSXに書かれている属性と子要素を単一のオブジェクトとしてこのコンポーネントに渡す。このオブジェクトのことをprops
と呼ぶ。
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
const root = React.DOM.createRoot(document.getElementById('root'));
const element = <Welcome name="Sara" />;
root.render(element);
上記のコードで起きていること
- という要素を引数として
root.render()
を呼び出す。 - ReactはWelcomeコンポーネントを呼び出し、その時にpropsとして
{name: 'Sara'}
を渡す。 - Welcomeコンポーネントは出力として
<h1>Hello, Sara</h1>
要素を返す。 - React DOMは
<h1>Hello, Sara</h>
に一致するように、DOMを効率的に更新する。
Reactの規約
小文字で始まるコンポーネント👉DOMタグとして扱う
例: <div />
はHTMLのdivタグを表す
大文字で始まるコンポーネント👉コンポーネント
コンポーネント名は常に大文字で始める
コンポーネントを組み合わせる
コンポーネントは自身の出力の中で、他のコンポーネントを参照できる
function Welcome(props) {
return <h1>Hello,{props.name}</h1>
}
function App() {
return (
<div>
<Welcome name="Sara" />
<Welcome name="Brown" />
<Welcome name="Edy" />
</div>
)
}
コンポーネントの抽出
コンポーネントをより小さなコンポーネントに分割することは恐れない。
なおコンポーネント自身は、どこでレンダーされるのかは知る必要ない。
コンポーネントの抽出をするタイミング
- UIの一部が複数回使われている場合
- UI自体が複雑である場合
コンポーネントの抽出は最初は面倒であるが、再利用できるコンポーネントをパレットとして持つことは、アプリケーションが大きくなれば努力に見合った利益を生み出す。
Propsは読み取り専用
コンポーネントを関数で宣言するかクラスで宣言するかに関わらず、自分自身のpropsを決して変更してはいけない。
以下のような関数は入力されたものを変更しようとせず、同じ入力に対し同じ結果を返すので純粋(pure)であると言われる。
function sum(a, b) {
return a + b;
}
対照的に以下の関数は入力されたものを変更するため純関数ではない。
function withdraw(account, amount) {
account.total -= amount;
}
全てのReactコンポーネントは、自己のpropsに対して純関数のように振る舞わねばならない。