Reactを勉強中にこんがらがったのでメモ
Reactのcomponentを作成する際には大きく2種類ありそれが
・Function Component
・Class Component
現在はFunction Componentを使うことを推奨されており、その理由についても調べてみました。
##そもそもComponentとは?
Reactでは複雑なUIをComponentという小さな部品を組み合わせて実現することが可能
Railsやってた人なら部分テンプレートをイメージするといいかも。
適度な粒度のコンポーネントに分けることで可読性と再利用性というメリットがある。
この適度な粒度に関してはAtomic Designという概念もある。
【参考】Atomic Designを使ってReactコンポーネントを再設計した話
####コンポーネントの主な登場人物
・JSX
・Props
・State
##JSX
JSXはhtml埋め込めるやつというざっくりとした考えの方もいるのではないでしょうか?
(自分もそう思っていました。 )
正確にはJSXはJavaScriptに変換さています。
Babelでコンパイルするとわかりやすいです。(右が変換後)
return <div>Hello React</div>
の部分が変換されている↓
return react.default.createElement("div", null, "Hello React");
見比べて見るとわかる通りJSXの方が記述量も少なく可読性も高いですね。
##Props
-コンポーネントの性質を表すもので不変
-親から子に情報を渡す
//子コンポーネント
import React from 'react';
const Box = props => {
return (
<div>{props.title}</div>
);
};
export default Box;
//親コンポーネント
import React from 'react';
import Box from './components/box'
export default App = () => {
return (
<Box title="Hello world" />
<Box title="Good bye world" />
);
};
オブジェクトスプレッド演算子を用いるとpropsを省略できる。
//子コンポーネント
import React from 'react';
const Box = ({ title }) => {
return (
<div>{title}</div>
);
};
export default Box;
※css省略
##State
-コンポーネントの状態を表すもので可変
-Stateを変更することで画面が更新される
##ここから本題
以前まではClass Componentではstate、ライフサイクル(componentDidMountなど)が使え、
Function Componentではそれらが使えないのが違いと言われていた。
しかし、現在ではHooksが導入されたことによりFunction ComponentでもuseState、useEffectなどを使って、
Stateやライフサイクルに相当するものが使えるようになっている。
##Function Componentを使うメリット
-記述が短くなる
-動作も少し早くなると言われている。(未検証)
例) 引用(React -ステートフックの利用法-)
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}
import React, { useState } from 'react';
function Example() {
//state関数呼び出し
const [count, setCount] = useState(0);
return (
<div>
//ClassComponentではthis.state.countで呼び出す
<p>You clicked {count} times</p>
//すでにcountとsetCountを受け取っているのでthisは不要
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
useStateは関数内で使うのでかなりスッキリ書けます。
次に副作用フックを見てみましょう。
上述のコードにクリック回数を含んだカスタムのメッセージをドキュメントのタイトルに表示してみます。
例) 引用(React -副作用フックの利用法-)
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
componentDidMount() {
document.title = `You clicked ${this.state.count} times`;
}
componentDidUpdate() {
document.title = `You clicked ${this.state.count} times`;
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
少しReact触った人ならuseEffectフックはcomponentDidMount、 componentDidUpdate、 componentWillUnmountがまとまったものと言うのがわかりますね。
上述だとドキュメントのタイトルをセットしているだけですが、
データを取得したり、その他何らかの命令型の API を呼び出したりすることも可能
//東京都最新コロナ感染者を取得
//自分のアプリに実装したものを少し書き換えてます。冗長なところあれば教えてください。。🙇♂️
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import Moment from 'moment';
import 'moment/locale/ja';
const DATA ='https://raw.githubusercontent.com/tokyo-metropolitan-gov/covid19/master/data/data.json';
function covidTokyo {
const [data, setData] = useState([]);
useEffect(() => {
fetchData();
}, []);
const fetchData = async () => {
try {
const response = await axios.get(DATA);
setData(response.data.patients_summary.data.slice(-1)[0]);
} catch (error) {
console.error(error);
}
};
Moment.locale('ja');
var dt = data['日付'];
return (
<div>
【東京都】新型コロナ新規感染者数({Moment(dt).format('MMMDo')}
<div>
+{data['小計']}名
</div>
</div>
);
};
##結論
Hooksが導入されたことでコードの記述量といい可読性といいFunction Componentを使うことが推奨されている理由がわかったと思います。
ただ、ネットで落ちている情報などはClass Componentで書かれているものが多いので、
Class ComponentとFunction Component両方の知識は付けておくのがいいのかなと。
React駆け出しなので間違っているところなどあれば教えて頂けると嬉しいです🙇♂️🙇♂️