React16.8で追加された「Hooks」を利用して、関数コンポーネントに「state」と「ライフサイクルメソッド」の機能を実装する方法を確認します。
目次
useState|state
概要
useState()
を利用すると、コンポーネントの状態管理を実装できます。
useState()
の引数にstateの初期値を指定する。useState()
は戻り値として、state変数
とstateを更新するための関数
を返す。- 複数のstateを使うには、複数回
useState()
を呼ぶ。
動作確認
import React, { useState } from 'react'
const App = ({ message }) => {
const [items, setItems] = useState(Array(9).fill(0))
const [flg, setFlg] = useState(false)
const handleClickItem = index => {
if (!flg) {
setFlg(true)
}
const newItems = items.slice()
newItems[index]++
setItems(newItems)
}
const handleResetItems = () => {
setFlg(false)
setItems(Array(9).fill(0))
}
return (
<div>
<p>{flg && message}</p>
<ul>{items.map((item, index) => {
return (
<li
key={index}
onClick={() => handleClickItem(index)}
>
{`Button${index}: ${item}`}
</li>
)
})}</ul>
<div onClick={handleResetItems}>Reset items</div>
</div>
)
}
export default App
実行イメージです。
devtools(3.6.0)でArrayの中身が表示されないようです。下記issueが作られていました。
https://github.com/facebook/react-devtools/issues/1282
参考
- https://reactjs.org/docs/hooks-overview.html#state-hook
- https://reactjs.org/docs/hooks-state.html
- https://reactjs.org/docs/hooks-reference.html#usestate
useEffect|ライフサイクルの代替
概要
useEffect()
は、クラスコンポーネントの以下メソッドが持つ役割をまとめたものです。
- componentDidMount
- componentDidUpdate
- componentWillUnmount
useEffect()
の動作の特徴です。
- 第一引数(関数指定)
componentDidMount
componentDidUpdate
で行っていた処理を指定する。- 関数の戻り値(
return
)の指定は任意。- 戻り値(
return
)で指定した処理が、コンポーネントの終了時に実行される。
(componentWillUnmount
に相当 )
- 戻り値(
- 第二引数(配列指定)
- 第一引数で指定した関数の実行タイミングを調整
- 指定しない場合、
初回レンダー時
と毎回の更新時
に実行される。 - 空配列で指定した場合(
[]
)初回レンダー時
のみ実行される。
- 特定stateを指定した場合( e.g.
[state1, state3]
)初回レンダー時
と指定stateの更新時
に実行される。
動作確認
( デフォルト )
import React, { useState, useEffect } from 'react'
const App = () => {
const [state1, setState1] = useState(0)
const [state2, setState2] = useState(0)
useEffect(() => {
console.log('useEffect')
})
const handleClickState1 = () => {
setState1(state1 + 1)
}
const handleClickState2 = () => {
setState2(state2 + 1)
}
return (
<div>
<p>{`state1: ${state1} state2: ${state2}`}</p>
<div onClick={handleClickState1}>Click1</div>
<div onClick={handleClickState2}>Click2</div>
</div>
)
}
export default App
useEffectの第二引数を指定していません。
初回レンダー時
と 毎回の更新時
にコンソール出力されています。
動作確認
( 初回と特定state更新時に実行 )
import React, { useState, useEffect } from 'react'
const App = () => {
const [state1, setState1] = useState(0)
const [state2, setState2] = useState(0)
useEffect(() => {
console.log('useEffect')
}, [state1])
const handleClickState1 = () => {
setState1(state1 + 1)
}
const handleClickState2 = () => {
setState2(state2 + 1)
}
return (
<div>
<p>{`state1: ${state1} state2: ${state2}`}</p>
<div onClick={handleClickState1}>Click1</div>
<div onClick={handleClickState2}>Click2</div>
</div>
)
}
export default App
useEffectの第二引数でstate1
のみ指定してます。
初回レンダー時
と state1の更新時
にコンソール出力されています。
動作確認
( 初回だけ実行 )
import React, { useState, useEffect } from 'react'
const App = () => {
const [state1, setState1] = useState(0)
const [state2, setState2] = useState(0)
useEffect(() => {
console.log('useEffect')
}, [])
const handleClickState1 = () => {
setState1(state1 + 1)
}
const handleClickState2 = () => {
setState2(state2 + 1)
}
return (
<div>
<p>{`state1: ${state1} state2: ${state2}`}</p>
<div onClick={handleClickState1}>Click1</div>
<div onClick={handleClickState2}>Click2</div>
</div>
)
}
export default App
useEffectの第二引数で空配列
を指定してます。
初回レンダー時
のみコンソール出力されています。
参考
- https://reactjs.org/docs/hooks-overview.html#effect-hook
- https://reactjs.org/docs/hooks-effect.html
- https://reactjs.org/docs/hooks-reference.html#useeffect