##ReactHooksでstateを扱う
###Hook(フック)とは
・クラスの機能(stateやライフサイクル)をFunctional Componentでも使えるというもの
・100%後方互換で、古い書き方のコンポーネントにReactHooksを使用したとしても影響を与えない
###Hook使用のメリット
####シンプルさを保てる為
クラスコンポーネントが複雑(難しい)
1.this.が入ることで他言語と違った挙動で使いづらい為、トレンド的に排除されようとしている
2.stateのロジックが複雑(stateだらけだと意味不明になる)
3.複数のライフサイクルメソッドにまたがる処理をまとめて記述できる
###Functional Componentでstateを使ってみる
・ステートフックと呼ばれる
・クラスコンポーネントでの
this.stateとthis.setstate()の役割
・複数のstateを扱うときはstate毎に宣言する必要がある
####useState()の使い方例
#####1.関数のインポート
import React, {useState} from 'react';
#####2.宣言
const [state変数名, state変更関数名] = usestate(state初期値);
//実際には↓
const [isHoge, setIsHoge] = useState(false);
#####3.JSX内で使う
<input /**中略 */ onClick={() => setIsHoge(!isHoge)} />
###Functional Componentでstateが使えると何がいいのか?
classコンポーネントを減らす為に上の階層がclassコンポーネントになることが多かった。それによりpropsをどんどん渡していかなければいけなかった為にコードが複雑化しやすかった。
Hookにより末端のコンポーネントでstateを持つことにより管理がしやすくなった。
##ReactHooks 関数コンポーネントでライフサイクルを扱う
###useEffect()を使用する
####メリット
・ライフサイクルの代替が可能
・Functional Componentでライフサイクルを使える(記述が減らせる)
・コードを(classComponentよりも分かりやすく)まとめれる
→時系列ベースではなく機能ベースでまとめが可能
###useEffect()の仕組み
・レンダーごとにuseEffect()内の処理が走るようになる
・メソッドの代替が可能
compnentDidMount()
compnentDidUpdate()
compnentWillUnmount()
###基本的な使い方
####①レンダーごと
・基本形でuseEffect()内にCallback関数で書く
・Callbackはレンダーごとに呼ばれる
・returnするCallback関数はアンマウント時に呼ばれる
(クリーンアップ関数とも言う)
useEffect(() => {
console.log('Render!')
return () => { //アンマウント時のみ
console.log('Unmounting!')
}
})
####②マウント時のみ実行させる
・compnentDidMount()の時にだけ書いていた処理を実行するパターン
・第2引数に空の配列を渡すとマウント時(最初の一回)だのみ実行される
→前回レンダーと今回レンダーで比較している
(変更があった場合のみCallback関数を実行)
useEffect(() => {
console.log('Render!')
}, [])
####③マウント、アンマウント時に実行する
・①と②の複合系
useEffect(() => {
console.log('Render!') //マウント時のみ実行される
return () => { //アンマウント時はクリーンアップ関数として実行される
console.log('Unmounting!')
}
}, []) //Updatingの期間は配列が空の為、実行されない
####④特定のレンダー時
・useState()と使われることが多い
const [limit, release] = useState(true);
useEffect(() => {
console.log('Render!') //limitの値を変更(true→false)時に実行される
}, [limit])
##いいねボタンの実装
import React, {useState, useEffect } from 'react';
const LikeButton = () => {
const [count, counter] = useState(0);
const [limit, release] = useState(true);
const countUp = () => {
counter(count + 1)
}
useEffect(() => {
document.getElementById('counter').addEventListener('click', countUp)
if (count >= 1000) {
counter (0)
}
return () => {
document.getElementById('counter').removeEventListener('click', countUp)
}
}, [limit]);
return(
<>
<button id={"counter"}> 👍 {count}</button>
<button onClick={() => release(!limit)}>もっと!!</button> {/*limitを解除するためのボタン*/}
</>
)
}
export default LikeButton