一瞬だけReact Hooksを触る。
【所要時間】
3時間(2019年2月15,16日)
【概要】
- React Hooksを使ってみる。
- useState, useEffectを使ってみる。
公式ページ参照
日本語翻訳はこちら参照
【要約・学んだこと】
Hooksとは?
とてもざっくりいうと、これのおかげで今までclass componentがなければ実装できなかったReactの機能が、stateless componentだけで実装できるようになるやつ。
使いやすそうな場面としては、「statelessで書いてたけどやっぱりstate持ちたい」ってなった時がある。propsをthis.propsに直したり、constructorとかを記述するよりは少ない記述量で修正ができるはず。
実感したことはないが、パフォーマンスの関係か何かで、極力class componentは使わない方がいいとどこかで読んだ記憶がある。
useStateの使い方
結構シンプル。
const [第一引数、第二引数 ] = useState(初期state);
第一引数:state名
第二引数:function名
useState:useStateを使う
初期state : initial state名
まずはuseStateをimportする。
import React, { useState } from 'react';
stateの名前がnum, initial stateが5だとすると
classの場合this.state = {
num: 5,
}Hooksの場合const [num, add] = useState(5);
と書けば良い。
constの第二引数は、numに関わるfunctionを使う時に必要となる。
クリックすると現在のnumに1を加算する式を書くと
classの場合onClick={
() => this.setState({
num: this.state.num + 1,
})
} Hooksの場合onClick={
() => add(num + 1)
}
となる。
onClick functionを別で記述する場合は
classの場合 constructor(props) {
super(props); ... this.changeNum = this.changeNum.bind(this);
}changeNum() {
const { num } = this.state;
this.setState({
num: this.state.num + 1,
});
} onClick={this.changeNum}
Hooksの場合const changeNum = () => add(num + 1);onClick={changeNum}
このようになる。
全体で比較すると
Classで書く(全部で75行)。
// src/components/class.jsximport React from 'react';class Class extends React.Component {
constructor(props) {
super(props);
this.state = {
num: 5,
str: 'str!!!',
arr: [1, 2, 3],
boo: true,
obj: {
number: 1,
strings: 'strrr',
boolean: false,
},
};this.changeStrings = this.changeStrings.bind(this);
}changeStrings() {
const { str } = this.state;
this.setState({
str: `${str}change`,
});
}render() {
const { num, str, arr, boo, obj } = this.state;return (
<div className="hooks">
<h2>ddd</h2>
<button type="button" onClick={() => this.setState({ num: num + 1 })}>
num
</button>
<p>{num}</p>
<button type="button" onClick={this.changeStrings}>
strings
</button>
<p>{str}</p>
<button
type="button"
onClick={() => this.setState({ arr: arr.concat(4) })}
>
array
</button>
<p>{arr}</p>
<button type="button" onClick={() => this.setState({ boo: !boo })}>
boolean
</button>
<p>{boo ? 'true' : 'false'}</p>
<button
type="button"
onClick={() =>
this.setState({
obj: {
...obj,
number: obj.number + 1,
strings: `${obj.strings}ddd`,
},
})
}
>
object
</button>
<p>{`number:${obj.number}`}</p>
<p>{`strings:${obj.strings}`}</p>
</div>
);
}
}export default Class;
Hooksで書く(全部で55行)。
// src/components/Hooks.jsximport React, { useState, useEffect } from 'react';const Hooks = () => {
const [num, add] = useState(5);
const [str, change] = useState('str!!!');
const [arr, push] = useState([1, 2, 3]);
const [boo, toggle] = useState(true);
const [obj, obChange] = useState({
number: 1,
strings: 'strrrr',
boolean: false,
});const changeStrings = () => change(`${str}change`);return (
<div className="hooks">
<h2>ddd</h2>
<button type="button" onClick={() => add(num + 1)}>
num
</button>
<p>{num}</p>
<button type="button" onClick={changeStrings}>
strings
</button>
<p>{str}</p>
<button type="button" onClick={() => push(arr.concat(4))}>
array
</button>
<p>{arr}</p>
<button type="button" onClick={() => toggle(!boo)}>
boolean
</button>
<p>{boo ? 'true' : 'false'}</p>
<button
type="button"
onClick={() =>
obChange({
...obj,
number: obj.number + 1,
strings: `${obj.strings}ddd`,
})
}
>
object
</button>
<p>{`number:${obj.number}`}</p>
<p>{`strings:${obj.strings}`}</p>
</div>
);
};export default Hooks;
ここまでで感じたHooksのメリット
- 行数が少ないから楽とは限らないが、Hooksで書いた方が記述量は少なくなりそう。
- 特にややこしい部分もないので、比較的簡単に移行できそう。
Classのメリット
- コードを読む時に、classの方がどこで何をやっているのか一目でわかりやすそう。
constructor内を見ればどのようなstateがinitial stateか、onClickなどの関数はどれで、どんな動作をするのか。
という2点が、classの場合は他のJSコードと若干違い、書く場所も決まっているので一目でわかる。
クラスの場合
Hooksの場合
useEffectの使い方
まずはimportする。
import React, { useState, useEffect } from 'react';
このように書く。
useEffect(() => {
document.title = 'useEffected!!!';
});
こんなかんじでタイトルが変更できた。
asyncなどを使いたい場合は、useEffectに直接宣言するのではなく、別の関数を用意し、useEffect内でそれを呼び出すようにする。
これは良くない。useEffect(async () => {
document.title = 'useEffected!!!';
});
こうする。
const title = async () => {
document.title = await 'awaitttt!';
};useEffect(() => {
title();
});
他にもcomponentDidMountなどのライフサイクルメソッドではできなかったことがHooksを使えばできる。が、ライフサイクルメソッドの使い方などがよくわかっていないので、今回はここまで。
【わからなかったこと】
特になし。
【感想】
まだよくわかっていないとは思うが、基本的な部分で覚える点は少ないようだ。
さよならReact,また会う日まで。