React Hooks、useStateの更新関数引数には関数を
最近 Hooks を触って思ったことを綴ります。よく見る useState の increment 例です。
const [count, setCount] = useState(0)
const handleClick = () => {
setCount(count + 1)
}
return (
<div className={props.className}>
<p>count: {count}</p>
<button onClick={handleClick}>+1</button>
</div>
)
これはアンチパターンで、handleClick
は render毎に再定義されます。この再定義を skip するため、useCallback
による関数memoizeを行います。
アンチパターン集
// memoize input array の指定がないため、上記と差がない
const handleClick = useCallback(() => {
setCount(count + 1)
})
// memoize されているが、状態変化とともに再定義される
const handleClick = useCallback(() => {
setCount(count + 1)
},[count])
// 2回目以降のレンダリング時再定義が skip されるが
// 初期状態を参照しているため「1」にしかならない。
const handleClick = useCallback(() => {
setCount(count + 1)
},[])
現状良さそうな方法
// memoize input array の指定がないため、上記と差がない
const handleClick = useCallback(() => {
setCount(count + 1)
})
// memoize されているが、状態変化とともに再定義される
const handleClick = useCallback(() => {
setCount(count + 1)
},[count])
// 2回目以降のレンダリング時再定義が skip されるが
// 初期状態を参照しているため「1」にしかならない。
const handleClick = useCallback(() => {
setCount(count + 1)
},[])
状態更新関数の引数に与えるものは、プリミティブに限りません。関数を与えることで、prev state を参照出来ます。これにより、初期レンダリング時のみに handleClick関数定義を抑止し、正しく動かすことが出来ます。
// 2回目以降のレンダリング時の再定義が skip され、正しく動く
const handleClick = useCallback(() => {
setCount(prev => prev + 1)
},[])
useState で生成された関数は、同時に生成された状態を参照しない方が良さそう、という話でした。
Author And Source
この問題について(React Hooks、useStateの更新関数引数には関数を), 我々は、より多くの情報をここで見つけました https://qiita.com/Takepepe/items/7e62cc7d7d8b81ca50db著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .